求助一道算法题。求思路。由一个 0 和 1 组成的矩阵,求出所有 1 构成的阶梯。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
letianqiu
V2EX    程序员

求助一道算法题。求思路。由一个 0 和 1 组成的矩阵,求出所有 1 构成的阶梯。

  •  
  •   letianqiu 2017-08-18 20:08:44 +08:00 4910 次点击
    这是一个创建于 2990 天前的主题,其中的信息可能已经有所发展或是发生改变。

    初步发现 size * (steps + 1) - steps = n,如果对于每一个元素都枚举一遍,感觉复杂度非常高,而且会重复,比如 size 为 2 的可能是 size 为 3 的其中一部分。求指导

    tmp.PNG

    33 条回复    2017-08-19 21:07:36 +08:00
    shard
        1
    shard  
       2017-08-18 20:25:56 +08:00
    动态规划
    menc
        2
    menc  
       2017-08-18 20:29:51 +08:00
    这是一道回溯法的题啊,
    只不过加了一个向右和向下的 step 必须一致的约束不是么
    letianqiu
        3
    letianqiu  
    OP
       2017-08-18 20:33:58 +08:00
    @menc 能否更加详细一点。要把所有的阶梯都找到, 感觉回溯只能找到一条最长的,而且如何避免重复呢。
    letianqiu
        4
    letianqiu  
    OP
       2017-08-18 20:37:21 +08:00
    @shard 能否具体一点。
    Magentaize
        5
    Magentaize  
       2017-08-18 20:40:58 +08:00
    行最简形矩阵
    shard
        6
    shard  
       2017-08-18 20:44:37 +08:00 via iPhone
    没审题,我沙壁。请无视
    bjrjk
        7
    bjrjk  
       2017-08-18 22:31:06 +08:00 via Android
    @shard 一楼说的就很对很好,就是动态规划
    geelaw
        8
    geelaw  
       2017-08-18 22:44:16 +08:00 via iPhone
    预处理每个位置开始往右往下可以有多少个 1,然后递推找出每个位置是否是某个阶梯的结束位置
    hezhe
        9
    hezhe  
       2017-08-19 00:54:45 +08:00 via Android
    能否使用 dfs?找到的点标记下,但有的点有又可能会出现新的阶梯中,要分类判断下。
    hxndg
        10
    hxndg  
       2017-08-19 02:49:43 +08:00
    好久没做题了。。。总感觉回溯或者搜索都必须注意时间复杂度啊,总感觉会爆栈
    Xs0ul
        11
    Xs0ul  
       2017-08-19 03:42:38 +08:00 via Android
    我想的居然是卷积,怕不是学傻了(
    victor97
        12
    victor97  
       2017-08-19 09:42:38 +08:00 via Android
    首先,每行每列求前缀和,可以快速判断某条线段是否全为 1。
    枚举所有位置,再枚举长度,向左上方找。
    因为不考虑重复,所以要找仅 1 step 的阶梯即可。
    总复杂度 O(n)
    letianqiu
        13
    letianqiu  
    OP
       2017-08-19 09:50:07 +08:00
    @victor97 需要考虑重复。当前我能想到的就是对每一个元素枚举,从 size 和 step 分别增长,找到存在的阶梯之后,比较是不是 map 里已有的 path 的其中一部分,如果是,就说明是重复的,放弃这条 path, 否则记录下 path,扔到 map 里。感觉复杂度至少 O(n^4)
    victor97
        14
    victor97  
       2017-08-19 09:56:22 +08:00 via Android
    是 起点相同,size 相同,step 不同 算重复吗,
    还是我理解错了重复的意思?
    letianqiu
        15
    letianqiu  
    OP
       2017-08-19 10:36:36 +08:00
    @victor97 算重复。这种情况下,只需要保留 steps 最大的。
    victor97
        16
    victor97  
       2017-08-19 10:57:42 +08:00 via Android
    我的意思其实也是重复的只算一次。
    从左至右,从上到下,枚举位置,那么只要判断左上方一个台阶就够了。
    如果要记录位置长度,再找到满足要求的更新坐标;如果不记录位置长度,只找一阶的数量就是答案。
    letianqiu
        17
    letianqiu  
    OP
       2017-08-19 11:16:18 +08:00
    @victor97 不是很明白你的意思诶。我算法水平太弱了。为什么只判断左上方一个台阶就可以。我的想法很初级,就是枚举每一个位置,往右下方走,size 从最小的 2 开始,step 从 1 开始,所有 step 找遍之后。size 增加。但是觉得这样有很多重复的。比如一个全都是 1 的 matrix,从( 0,0 )开始可以走到底,当从( 1,1 )开始走时,很多路径其实在( 0,0 )的时候都走过了, 属于无效的。
    victor97
        18
    victor97  
       2017-08-19 11:26:47 +08:00 via Android   1
    因为左上方的所有位置都是统计过的,如果发现能组成一阶台阶,要么是新出现的台阶,要么之前就已经是台阶了,只是长度 + 1,算重复。
    letianqiu
        19
    letianqiu  
    OP
       2017-08-19 11:33:46 +08:00
    @victor97 明白了。不过你说的求前缀和有什么用,就算知道了某列或者某行全为 1,并不能说明什么啊。还是需要枚举每一个位置。
    letianqiu
        20
    letianqiu  
    OP
       2017-08-19 11:50:37 +08:00
    @victor97 还有个问题,怎么区分是新台阶还是长度+1 的旧台阶。是不是和我原始的想法类似,开 map 保留所有已知的台阶构造,如果不是新台阶,那么当前位置(x, y)的上方(x-1, y)和左上方(x-1, y-1)是属于已经存在的台阶的构造的一部分,此时将原始台阶的长度+1,否则就是新台阶,加入 map
    imn1
        21
    imn1  
       2017-08-19 12:13:56 +08:00
    原矩阵把 行 中连续的 1 保留,其他置为 0,得到新矩阵 A
    原矩阵把 列 中连续的 1 保留,其他置为 0,得到新矩阵 B
    AB 的交集(逻辑与)就是阶梯的角

    后面自己推吧
    imn1
        22
    imn1  
       2017-08-19 12:18:22 +08:00
    楼上#21 说的不严谨,但原题也没有说清楚

    #21 说的是 转角
    还需要排除“断层”
    letianqiu
        23
    letianqiu  
    OP
       2017-08-19 12:23:24 +08:00
    @imn1 如果全都是 1 的矩阵,这么操作之后,并没有任何变化啊。要求就是 i 找出所有的形如图片中的台阶。觉得#18 说得有道理啊
    imn1
        24
    imn1  
       2017-08-19 12:43:24 +08:00
    @letianqiu
    实际上我就是搞不清楚你原题中阶梯的定义
    例如
    11000
    01000
    01000
    011111
    这种是否也算阶梯

    其实最简单的方法就是
    把所有符合阶梯定义的图形都写出来,然后去矩阵中找交集(平移和竖移)
    这里问题就是矩阵越大,那阶梯图形就越多,而且阶梯不明确定义横向最大连续和纵向最大连续的话,阶梯的变化很多

    反正思路不应该是在矩阵中逐点“画”阶梯,而是把已知定义的阶梯整体在矩阵中匹配
    mrcn
        25
    mrcn  
       2017-08-19 12:47:05 +08:00 via Android
    @shard 二维 dp 感觉可以做吧
    只是想不出转移方程
    letianqiu
        26
    letianqiu  
    OP
       2017-08-19 12:53:05 +08:00
    @imn1 你给的这个例子不属于阶梯。阶梯必须是横向和纵向的长度相等。你的方法好高深。
    letianqiu
        27
    letianqiu  
    OP
       2017-08-19 12:54:53 +08:00
    @mrcn 对啊。对于状态转移方程这题完全没有思路。目前觉得#18 楼的方法比较可行。#21 的方法对我来说太过于高深了。大致能理解他的意思,但是完全驾驭不了
    victor97
        28
    victor97  
       2017-08-19 13:24:37 +08:00   1
    @letianqiu #20
    满足一阶台阶且不满足二阶台阶的就是新台阶。
    另外,不需要用 map,每个位置记录以它为结尾的所有阶梯就行。
    victor97
        29
    victor97  
       2017-08-19 13:28:50 +08:00
    @letianqiu #19
    前缀和是快速判断某个区间全为 1 用的。
    如果不用前缀和,每次判台阶的复杂度和是 size*step ;使用前缀和优化为 step。
    victor97
        30
    victor97  
       2017-08-19 13:32:59 +08:00
    @letianqiu
    使用前缀和判断是否是新台阶的复杂度是常数级别的。
    letianqiu
        31
    letianqiu  
    OP
       2017-08-19 14:16:46 +08:00
    @victor97 大致明白了。受益匪浅啊。非常感谢啊。只是对于“另外,不需要用 map,每个位置记录以它为结尾的所有阶梯就行。”还有点点疑问。每个位置可能是不同 size 的阶梯的结尾,如果不开个 map 保存,如何能够记录。也许我没表达清楚题目要求,题目需要记录所有 size (宽度)下所有不同 steps (高度)的阶梯。所以我就想保存一个 map,key 是 size,value 还是一个 map,这个 map 的 key 是 steps,value 是阶梯的结尾位置的坐标。一个位置不可以出现在同一个 size 下,不同的高度的阶梯里。但是可以出现在不同的 size 的阶梯中。
    letianqiu
        32
    letianqiu  
    OP
       2017-08-19 19:44:45 +08:00
    @victor97 再次感谢你啊。按照你的思路,我基本上实现了。就是关于前缀和那一块没懂,我是用了五个 for 循环判断台阶的。比较傻
    Xs0ul
        33
    Xs0ul  
       2017-08-19 21:07:36 +08:00
    @imn1 #23 拿已知定义匹配倒是和我想到一块儿去了,用卷积就行(
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2398 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 04:51 PVG 12:51 LAX 21:51 JFK 00:51
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86