一起刷LeetCode——累加数(DFS)

76 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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的同时,可能还需要维护一些变量来供剪枝或者回溯来优化算法,所以这类题目不怎么提及时空复杂度,但是题解代码写出来会比较清晰
  • 今天也是有收获的一天