每日一题-累加数(中等)

156 阅读1分钟

306. 累加数

一、题目描述

累加数 是一个字符串,组成它的数字可以形成累加序列。

一个有效的 累加序列 必须 至少 包含 3 个数。除了最开始的两个数以外,字符串中的其他数都等于它之前两个数相加的和。

给你一个只包含数字 '0'-'9' 的字符串,编写一个算法来判断给定输入是否是 累加数 。如果是,返回 true ;否则,返回 false 。

说明: 累加序列里的数 不会 以 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

提示:

  • 1 <= num.length <= 35
  • num 仅由数字(0 - 9)组成

三、分析

依题意,给定一个只包含数字 '0'-'9' 的字符串,判断它是否为累加数。 累加数至少包含三个数,且整个字符串均可有最开始的两个数确定,所以我们只需枚举第一个数和第二个数,然后判断由第一个数和第二个数构成的字符串与给定字符串中第二个字符串相邻的相同长度字符串是否相等即可。若相等,则继续判断下一个数,否则返回false。

复杂度分析:

O(n3)O(n^3),其中 n 为字符串 num 的长度。需要两层循环来遍历第一个数和第二个数,每个这样的组合又需要 O(n)O(n) 来验证合法性,所以总的时间复杂度为 O(n3)O(n^3)

四、编码

大佬的写法:
class Solution {
    public boolean isAdditiveNumber(String num) {
        boolean res = false;
        long num1 = 0;
        for(int i=0; i<num.length()/2&!res; i++){
            num1 = num1*10 + num.charAt(i) - '0';
            long num2 = 0;
            for(int j=i+1; j<num.length()-1&!res; j++){
                num2 = num2*10 + num.charAt(j) - '0';
                res |= recur(num, j+1, num1, num2);
                if(num.charAt(i+1)=='0') break;
            }
            if(num.charAt(0)=='0') break;
        }
        return res;
    }
    boolean recur(String num, int pos, long num1, long num2){
        if(pos>=num.length()) return true;
        long sum = 0;
        boolean res = false;
        for(int i=pos; i<num.length()&!res; i++){
            sum = sum*10 + num.charAt(i) - '0';
            if(num1 + num2 == sum) res |= recur(num, i+1, num2, sum);
            if(sum-num2>num1||num.charAt(pos)=='0') break;
        }
        return res;
    }
}

题目链接