leetcode306-累加数

给定一个只包含数字 ‘0’-‘9’ 的字符串,编写一个算法来判断给定输入是否是累加数。

说明: 累加序列里的数不会以 0 开头,所以不会出现 1, 2, 03 或者 1, 02, 3 的情况。

示例 1:

输入: "112358"
输出: true 
解释: 累加序列为: 1, 1, 2, 3, 5, 8 。1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8

示例 2:

输入: "199100199"
输出: true 
解释: 累加序列为: 1, 99, 100, 199。1 + 99 = 100, 99 + 100 = 199

进阶:

  • 你如何处理一个溢出的过大的整数输入?

一、思路

首先,想想难点是什么,有哪些部分很难处理:

  • 如何划分数字?
  • 大数相加问题
  • 怎么样才能遍历所有的可能组合?
  • 最后,该题属于哪一类型的题目?

接下来一个一个的回答上述四个问题。

1、如何划分数字?

每次验证前两个数之和时,需要先确定这两个数,可是我们事先并不知道数字有多长,也不确定第二个数字的起始位置,于是要做的是:

  • 确定第一个数字的长度len1
  • 如此一来,第二个数字起始位置就确定下来了
  • 接着确定其长度为len2
  • 于是需要验证的数字的起始位置也确定了,其长度与前两数之和的长度一致

通过上述4个步骤,可以确定一次验证结果,此时分为两种情况:

(1)验证成功

验证成功时,可以进入下一轮次验证:

  • 将数字往前挪动一位,即:之前的第二个数字变为第一个数字
  • 原本验证成功的数字变为第二个数字
  • 此时前两位数字已经确定下来了,于是第三个数字的首位可以确定
  • 又因为前两个数字已经确定,其和也能很快计算出来,第三个数字的长度也就确定了

这就像骨诺米牌一样,一旦第一轮中的某次验证匹配了,剩下的轮次就不需要划分数字,直接匹配下去直到成功或者失败

(2)验证失败

这次验证失败并不代表本轮匹配失败,可以考虑增加第一个数字或者是第二个数字的长度,再参与比较验证,准确的说,就是我们需要遍历所有可能的组合,当所有的组合都失败了,我们才能说这一轮次匹配失败,结果返回false

2、大数相加问题

采用字符串加法,从末位加起

3、怎么样才能遍历所有的可能组合?

这个问题才是本题的关键所在,我们如何遍历所有可能的组合?

根据之前的分析,我们只需要找出第一轮中的所有组合即可,因为在第一轮中出现匹配之后,可以通过递归来确定,该配对是否成功。

C++代码:

class Solution {
public:
    bool isAdditiveNumber(string num) {
        int i1 = 0, len = num.size();
        bool flag = false;
         for(int len1=1; len1 < len; len1++){
            string s1 = num.substr(i1, len1);
            if(s1[0] == '0' && len1 > 1)
                break;
            for(int len2=1; len2 < len; len2++){
                int i2 = i1 + len1;
                string s2 = num.substr(i2, len2);
                if(s2[0] == '0' && len2 > 1)
                    break;
                string sum = addString(s1, s2);
                int len3 = sum.size(), i3 = i2 + len2;
                if(i3 + len3 > num.size())
                    break;
                string s3 = num.substr(i3, len3);
                if(sum == s3){
                    flag = dfs(num, s2, s3, i3 + len3);
                }
                if(flag)
                    return flag;
            }
        }       
        return false;
    }

    bool dfs(string& num, string& s1, string& s2, int i3){
        if(i3 == num.size())
            return true;
        string sum = addString(s1, s2);
        int len3 = sum.size();
        if(i3 + len3 > num.size())
            return false;
        string s3 = num.substr(i3, len3);
        if(s3 == sum)
            return dfs(num, s2, s3, i3 + len3);
        else
            return false;
    }

    string addString(string& s1, string& s2){
        string ans;
        int i = s1.size() - 1, j = s2.size() - 1;
        int carry = 0, p;
        while(i >= 0 && j >= 0){
            int t1 = s1[i] - '0', t2 = s2[j] - '0';
            int temp = t1 + t2 + carry;
            carry = temp / 10;
            p = temp % 10;
            char ch = p + '0';
            ans = ch + ans;
            i--;
            j--;
        }
        while(i >= 0){
            int t1 = s1[i] - '0';
            int temp = t1 + carry;
            carry = temp / 10;
            p = temp % 10;
            char ch = p + '0';
            ans = ch + ans;
            i--;
        }
        while(j >= 0){
            int t2 = s2[j] - '0';
            int temp = t2 + carry;
            carry = temp / 10;
            p = temp % 10;
            char ch = p + '0';
            ans = ch + ans;
            j--;
        }
        if(carry){
            char ch = carry + '0';
            ans = ch + ans;
        }
        return ans;
    }
};

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章