携手创作,共同成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情
累加数
累加数 是一个字符串,组成它的数字可以形成累加序列。 一个有效的 累加序列 必须 至少 包含 3 个数。除了最开始的两个数以外,序列中的每个后续数字必须是它之前两个数字之和。 给你一个只包含数字
'0'-'9'
的字符串,编写一个算法来判断给定输入是否是 累加数 。如果是,返回true
;否则,返回false
。
分析
- 给出一个字符串判断是否是累加数,重要的是确定累加序列的最开始的两个数,但是最开始的两个数的长度是多少,这个时候就需要分情况
- 对于需要不断尝试的解题思路,可以使用DFS遍历,遍历的时候以字符串的位置作为遍历属性,同时因为需要第三个数是前两个数的和,所以在遍历的时候需要维护一个类似滑动窗口的三个数的数组,如果当前遍历到的第三个数是第一个数字和第二个数字的和,就把这个时候就把第一个数字出数组,把当前数字进数组,维持这个数组的长度一直是3,如果不能匹配,就把数组中的数组出数组,直到遍历完成,此时把维护的这个数组取出来,如果数组长度不等于0,那就是累加数,如果是0就不是累加数
代码
var isAdditiveNumber = function(num) {
let s, n, res, find;
s = num;
n = s.length;
res = [];
find = false;
dfs(0, []);
return res.length != 0;
const dfs = (pos, cur) => {
if (pos == n && ok(cur)) {
res = cur;
find = true;
return;
}
for (let i = pos; i < n; i++) {
let third = s.slice(pos, i + 1);
if (cur.length > 2 && !ok(cur)) break;
cur.push(third);
dfs(i + 1, cur);
if (find) break;
cur.pop();
}
};
const ok = (a) => {
if (a.length < 3) return false;
for (const s of a) {
if (s[0] == '0' && s.length > 1) return false;
}
a = a.map(Number);
for (let i = 0; i + 2 < a.length; i++) {
if (a[i] + a[i + 1] != a[i + 2]) return false;
}
return true;
};
};
总结
- 在很多题目描述中涉及到不断尝试的过程,这时都会比较适合DFS,在DFS的同时,可能还需要维护一些变量来供剪枝或者回溯来优化算法,所以这类题目不怎么提及时空复杂度,但是题解代码写出来会比较清晰
- 今天也是有收获的一天