306. Additive Number解题报告

题目

Additive number is a string whose digits can form additive sequence.

A valid additive sequence should contain at least three numbers. Except for the first two numbers, each subsequent number in the sequence must be the sum of the preceding two.

For example:

“112358” is an additive number because the digits can form an additive sequence: 1, 1, 2, 3, 5, 8.

1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8

“199100199” is also an additive number, the additive sequence is: 1, 99, 100, 199.

1 + 99 = 100, 99 + 100 = 199

Note: Numbers in the additive sequence cannot have leading zeros, so sequence 1, 2, 03 or 1, 02, 3 is invalid.

Given a string containing only digits ‘0’-‘9’, write a function to determine if it’s an additive number.

题目分析

题目意思是说,给定一个字符串s, 求解里面是否含有递增的数字序列(斐波那契数列), 该数字序列至少包含3个数字,而且不能出现以0开头的多位数

思路分析

这道题的突破口在于要找到前两个数字,使这两个数字的和等于剩余字符串的开头数字。首先对于第一个数字,它肯定是从位置0开始,最长长度为(num.length() - 1) / 2。举个例子,比如一个字符串的长度为10,那么第一个数字的长度就不能超过4,对于一个字符串长度为11的例子,第一个数字的长度就不能超过5。

对于第二个数字,设第一个数字的结束位置为i(不包含i),那么第二个数字的开始位置为i,设第二个数字的结束位置为j(不包含j),那么对于第三个数字,它的开始位置就为j,第二个数字的长度是j-i,第三个数字的长度是num.length()-j,由于数字是递增的关系,因此第三个数字的长度必须要大于等于第一个和第二个数字的长度,因此存在循环的约束条件:num.length()-j >= j-i && num.length() - j >= i

当把第一个,第二个,第三个数字都确定时候,如果存在第一个数字加上第二个数字等于第三个数字,那么将剩余的子序列进行递归判断,递归判断的结束条件为剩余的字符串为空,或者第一个数字加上第二个数字不等于第三个数字

注:使用int会过不了一个例子,”121474836472147483648”,在这里可以分开1+2147483647=2147483648,但是2147483648对于int来说已经溢出,因此需要使用unsigned int

AC代码

#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;
class Solution {
public:
    unsigned int str_2_int(string num) {
        stringstream ss;
        ss<<num;
        unsigned int result;
        ss>> result;
        return result;
    }
    string int_2_str(unsigned int num) {
        stringstream ss;
        ss<< num;
        return ss.str();
    }
    bool isAdditiveNumber(string num) {
        if (num.length() <= 2) return false;
        for (int i = 1; i <= (num.length() - 1)/2; ++i) {
            if (num[0] == '0' && i >= 2) break;
            for (int j = i + 1;(num.length() - j) >= i && (num.length() - j) >= j - i;j++) {
                if (num[i] == '0' && j - i >= 2) break;
                unsigned int firstnum = str_2_int(num.substr(0, i));
                unsigned int secondnum = str_2_int(num.substr(i, j - i));
                if (isAdditiverecursion(num.substr(j), firstnum, secondnum)) return true;
            }
        }
        return false;
    }
    bool isAdditiverecursion(string left, unsigned int num1, unsigned int num2) {
        if (left.length() == 0) return true;
        unsigned int num = num1 + num2;
        string numstr = int_2_str(num);
        if (left.find(numstr) != 0) return false;
        return isAdditiverecursion(left.substr(numstr.length()), num2, num);
    }
};

int main() {
    string s = "121474836472147483648";
    Solution ss;
    cout <<  ss.isAdditiveNumber(s) << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值