306 累加数

题目描述:
累加数是一个字符串,组成它的数字可以形成累加序列。
一个有效的累加序列必须至少包含 3 个数。除了最开始的两个数以外,字符串中的其他数都等于它之前两个数相加的和。
给定一个只包含数字 ‘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:
主要思路:
(1)确定初始的两个数字,剩下的按照顺序判断即可;
(2)判断的条件是相加之和是否等于后面的字符串,则为了避免溢出,可以定义一个字符串相加函数;
(3)获得两个字符串后,若相加之和是后面的字符串,则接着递归判断,直到不符合或恰好按照该规律分割了字符换即可;

class Solution {
public:
	//定义的字符串相加函数
    string add_string(string& lhs,string& rhs){
        int len_l=lhs.size()-1;
        int len_r=rhs.size()-1;
        string res;
        int add_1=0;//表示进位的1
        while(len_l>=0||len_r>=0||add_1==1){
        	//获得两个字符串对应索引上的字符对应的数字
            int n_1=len_l>=0?(lhs[len_l--]-'0'):0;
            int n_2=len_r>=0?(rhs[len_r--]-'0'):0;
            //获得结果字符
            res+=(n_1+n_2+add_1)%10+'0';
            //判断进位
            add_1=(n_1+n_2+add_1)/10;
        }
        reverse(res.begin(),res.end());//反转字符串,获得结果字符串
        return res;
    }
    //递归判断字符串的有效性
    bool dfs(int left,int mid,int right,string&num){
        if(num[left]=='0'&&mid-left!=1){//左边的字符串是有效的字符串,既字符的首位不是0,或是0的情形下,对应的字符串只能是一位的长度,否则直接返回false
            return false;
        }
        if(num[mid]=='0'&&right-mid!=1){//判断右边的字符串无效
            return false;
        }
        //获得有效的左右两个字符串
        string str_1=num.substr(left,mid-left);
        string str_2=num.substr(mid,right-mid);
        //获得两个字符串相加的结果
        string str_sum=add_string(str_1,str_2);
        //首先判断长度上是否是正确的,既字符串之和在长度上能够满足原字符串长度的条件,否则直接返回false
        if(str_sum.size()+right>num.size()){
            return false;
        }
        //在长度满足条件下,判断字符串的和字符串是否和给定的字符串的后面子串一致
        for(int pos=0;pos<str_sum.size();++pos){
            if(num[right+pos]!=str_sum[pos]){//若存在不一致,则直接返回false
                return false;
            }
        }
        //上面的字符串之和满足要求后,判断此时长度是否刚好满足给定字符串的条件,满足的话,说明分割成功,直接返回true
        if(str_sum.size()+right==num.size()){
            return true;
        }
        //若字符串没有分割完,则接着分割剩余的字符串部分
        return dfs(mid,right,right+str_sum.size(),num);
    }
    bool isAdditiveNumber(string num) {
        if(num.size()<3){//处理特殊的情形
            return false;
        }
        //终止条件
        int end_pos=num.size()/2;
        //找出所有的可能的第一个字符串和第二个字符串的组成情形
        for(int i=1;i<=end_pos;++i){//第一个字符串的终止位置,其实位置为0
            for(int j=i+1;j<num.size();++j){//第二个字符串的终止位置,起始位置为第一字符串的终止位置
            	//剪枝操作,但作用不大
                //if(num[i]=='0'&&i+1!=j&&num[i+2]!='0'){
                //    continue;
                //}
                if(dfs(0,i,j,num)){//若能够在这两个子字符串的情形,可以将原来的分割成功,则直接返回true
                    return true;
                }
            }
        }
        //若所有的情形都不能分割字符串,则返回false
        return false;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值