题目
最近在LeetCode上看到这么一道链接题目
给定一个由正整数组成的数组C和一个目标数字T,查找C中所有的唯一组合,其中候选数字总和为T。
从C中抽出的数字可以无限重复。
来个例子: 数组[2, 3, 6, 7]
和 目标 7
[2,4,5,8]
需要返回
[
[7],
[2, 2, 3]
]
解答
看完题目一开始想的是把7%2,如果余0或者有与余数相等的值做为一个解。如 7%2=1, 2 + 1 = 3 --> [2, 2, 3], 但是一碰到 数组[2, 4, 5]
和 目标 8
的情况解歇菜了。
后面又想到了一种方式,一直累减:x_x
标准答案
深度优先搜索算法(英语:Depth-First-Search,简称DFS)是一种用于遍历或搜索树或图的算法。沿着一个方向如果有未搜索的节点就一直搜索下去。
深度优先的主要思想就是“不撞南墙不回头”,“一条路走到黑”,如果遇到“墙”或者“无路可走”时再去走下一条路。
就像下图,按照优先级为右下左上顺时针的方式尝试移动,先往右走,但是有堵墙走不了,所以尝试往下走,如果发现右下左上全都走不了了,就返回到上一个节点进行移动如3 -> 4, 25 -> 26 就是返回到上一个节点。 所以 递归没得跑了。
在代码实现上也有标准的模板:
void dfs()
{
// 判断是否到达终点
if() {
return;
}
// 尝试每一个可走方向(右下左上)
for(i=0; i<n; i++){
// 判断是否可走,可走调用递归尝试下一步,不可走则尝试该点的其他方向
if () {
// 继续下一步
dfs();
}
}
}
然后再把我们题目往模板里面一套
var combinationSum = function(candidates, target) {
let result = []
let temp = []
dfs(0, 0, temp)
return result
function dfs(value, index, temp) {
// 判断累加和是否为target 或者 超出了 target
if (value === target) {
// 如果和为target就把当前的数组记录下来保存
result.push(temp.concat())
return
} else if (value > target) {
return
} else {
for (let i = index, len = arr.length; i < len; i++) {
// 记录下之前累加的数字
let newtemp = temp.concat(arr[i])
// 继续下一步
dfs(value + arr[i], i, newtemp)
}
}
}
}
LeetCode上还有性能更加好的解法,大家可以自己去观摩一番,提高一下姿势水平。
因发明“深度优先搜索算法”,约翰·霍普克洛夫特与罗伯特·塔扬共同获得计算机领域的最高奖:图灵奖。
做完这题最大的感受就是,智商不够,套路来凑,得把基础的数据结构和算法知识看熟啰。
ass♂we♂can
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。