如何解决在二维数组中找到可被 3 整除的最大路径
给定一个二维数字数组。
找到“蛇形路径”,而:
-
在蛇形路径中,每行需要一个元素,并且在相邻的两行中,元素在相邻的列中
-
“snake path”的总和需要是最大值并且可以被 3 整除(元素本身不一定要被 3 整除)
我多年来一直试图解决这个问题。 到目前为止我尝试过的是:
我计算出有 n^3 条潜在的蛇路径,每条蛇路径的长度为 n,然后我只需循环遍历 n^3 条潜在的蛇路径并检查哪一个具有最大总和并且可以被除以3.
问题是这种方法效率不高,需要 O(n^4),这很慢,而且这个问题似乎可以使用动态编程来解决。
任何帮助将不胜感激
解决方法
我确实发现这是一个有趣的问题。这是一个潜在的解决方案,它将找到如下路径:
Start at index 5 ---v
__
7 6 5 4 3 | 2| 1 (start) 2
'--\ __
2 4 6 8 10 12 |14| (right) + 14
__ /--'
2 7 1 8 2 | 8| 1 (left) + 8
__ /--'
3 1 4 1 | 5| 9 2 (left) + 5
'--\ __
2 3 5 7 11 |13| 17 (right) + 13
'--\ __
8 6 7 5 3 0 | 9| (right) + 9
'--' ----
total: 51
会像这样报告:
{path: "RLLRR",startIndex: 5,total: 51}
实现如下:
const maxMod3Path = (grid) =>
[...grid] .reverse () .reduce ((prev,row,ri) => row .map ((c,i) =>
[
...(prev [i - 1] || []).map(({n,p}) => ri == 0 ? {n,p} : ({n,p: 'L' + p})),...(prev [i + 1] || []).map(({n,p: 'R' + p})),]
.map (({n,p}) => ({n: n + c,p}))
.reduce (
(a,{n,p}) => {a [n % 3] = (n > a [n % 3] .n ? {n,p} : a [n % 3]); return a},[{n: 0},{n: 0},{n: 0}]
)
),grid [0] .map ((c) => [{n: 0,p: ''},{n: 0,p: ''}])
)
.map (([{n,p}],startIndex) => ({total: n,path: p,startIndex}))
.reduce ((a,x) => x.total > a.total ? x : a,{total: 0})
const grid = [
[ 7,6,5,4,3,2,1 ],[ 2,8,10,12,14 ],7,1,[ 3,9,2 ],11,13,17 ],[ 8,9 ],]
console .log (maxMod3Path (grid))
我现在没有时间对此代码进行详细解释,但简要说明这是使用动态编程,遵循 Ehsan Gerayli 描述的算法。我们从每行宽度的数组开始,每个条目包含 {n: 0,p: ''}
的三个副本的数组,每个副本用于 0
、1
和 2
模数结果3
。
从底行开始,我们计算每个单元格通过从单元格向下或向左或向右移动找到的结果,如果总数大于当前值,则将总数和路径存储在正确的模桶中存储桶的值。
最后,我们存储了每个存储桶的最大值。我们现在可以删除 1
和 2
存储桶,重命名变量并包括要开始的索引。 (.map (([{n,startIndex}))
)
这会给我们这样的东西:
[
{path: "RLRRR",startIndex: 0,total: 24},{path: "RRRLL",startIndex: 1,total: 39},{path: "LRRRL",startIndex: 2,total: 27},{path: "LRRRR",startIndex: 3,total: 45},{path: "RLRLL",startIndex: 4,total: 42},{path: "RLLRR",total: 51},{path: "LRLLL",startIndex: 6,total: 39}
]
然后,最后一行中的 reduce
调用选择总数最大的那个。
我认为我的要求是正确的。但是如果一条路径也可以直线下降,你也可以在明显的地方添加:
...(prev [ i ] || []).map(({n,p: 'D' + p})),
现在将产生结果
{path: "RRDRD",total: 57}
最后,如果您的网格可以包含负数,那么您应该将所有 {n: 0}
实例替换为 {n: -Infinity}
。 (这没有经过彻底的测试,但看起来它会起作用。)
我想知道这是否符合要求。
,首先声明I calculated that there are n^3 potential snake paths
是错误的,还有很多情况实际上是O(2^n)
您可以使用以下动态方法,即 O(n^2)
- 开始时只保留数组的最后一行,每一步从底部开始逐行添加
- 在每个步骤中,假设您为 Current_Array 的每个单元格保留这 3 个值
- SUM % 3 ==0 的最大路径,SUM % 3==1 和 ...==2 的最大路径
- 对于新添加的行,您可以轻松地从它的底行计算这 3 个参数,例如对于索引 (i,j) 只需检查 (i+1,j+1) 和 (i+1) 的 3 个参数,j-1) 并根据 index(i,j)%3 的值计算其参数
- 最后找到 O(n^2) 数组中 (SUM % 3 ==0) 参数的最大值
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。