回溯练习(leetcode306累加数)

累加数 是一个字符串,组成它的数字可以形成累加序列。一个有效的 累加序列 必须 至少 包含 3 个数。除了最开始的两个数以外,序列中的每个后续数字必须是它之前两个数字之和。给你一个只包含数字 ‘0’-‘9’ 的字符串,编写一个算法来判断给定输入是否是 累加数 。如果是,返回 true ;否则,返回 false 。说明:累加序列里的数,除数字 0 之外,不会 以 0 开头,所以不会出现 1, 2, 03 或者 1, 02, 3 的情况。
示例 1:
输入:"112358"
输出:true 
解释:累加序列为: 1, 1, 2, 3, 5, 81 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8

示例 2:
输入:"199100199"
输出:true 
解释:累加序列为: 1, 99, 100, 1991 + 99 = 100, 99 + 100 = 199
思路:给定的 nums 的长度只有 35,而且要求序列的第三个数开始由前两个数相加而来。因此使用 DFS 搜索每个数的分割点,同时利用累加数的特性(第三个数起,每个数均由为前两数之和)进行剪枝。具体的。因为数字不包含前导0,所以当前数字为0时,需要把它单独作为一个数字。如果结果的result集合长度小于2,则可以直接添加current集合,如果大于2则需要进行判断当前集合和前两个集合是否满足题意要求,即a+b是否等于c。
class Solution {
    List<List<Integer>> result = new ArrayList<>();
    int len;
    String num;
    public boolean isAdditiveNumber(String num) {
        this.num = num;
        len = num.length();
        return dfs(0);
    }
    public boolean dfs(int start){
        int m = result.size();
        if(start == len)
            return m >= 3;
        List<Integer> current= new ArrayList<>();
        int max = num.charAt(start)=='0'?start+1:len;
        for(int i = start; i < max; i++){
            current.add(0,num.charAt(i)-'0');
            if(m < 2 || isTrue(result.get(m-2),result.get(m-1),current)){
                result.add(current);
                if(dfs(i+1))
                    return true;
                result.remove(result.size()-1);
            }
        }
        return false;
    }
    public boolean isTrue(List<Integer> a,List<Integer> b,List<Integer> c){
        List<Integer> ans = new ArrayList<>();
        int temp = 0;
        for(int i = 0; i < a.size() || i < b.size(); i++){
            if(i < a.size())
                temp += a.get(i);
            if(i < b.size())
                temp += b.get(i);
            ans.add(temp%10);
            temp /= 10;
        }
        if(temp > 0){
            ans.add(temp);
        }
        boolean flag = ans.size() == c.size();
        for(int i = 0; i < ans.size()&&flag; i++){
            if(ans.get(i) != c.get(i)){
                flag = false;
            }
        }
        return flag;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值