zoukankan      html  css  js  c++  java
  • LeetCode-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.

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

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

    题目大意

    字符串中包含‘0’-‘9’的数字,要求判断该数字字符串是否是可加序列。

    (可加序列:前两个数字相加等于后一个数字,字符串中的所有数字均满足这个规则)

    (PS:数字不会包含前缀‘0’,如‘02’或‘03’等,但会包含后缀‘0’,如‘200’等。此外,输入的数字可能会很大,超过long long)

    示例

    E1

    Input: "112358"
    Output: true 
    Explanation: 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

    E2

    Input: "199100199"
    Output: true 
    Explanation: The additive sequence is: 1, 99, 100, 199. 
                 1 + 99 = 100, 99 + 100 = 199

    解题思路

    外循环取出两个可能的数字,将数字送入内部递归函数,递归函数内将输入的两个数字相加,并判断是否与后续数字相等,若相等则继续递归,否则返回外层循环从新输入两个数字。

    复杂度分析

    时间复杂度:O(N2)

    空间复杂度:O(N)

    代码

    class Solution {
    public:
        bool isAdditiveNumber(string num) {
            // 遍历数字字符串,将两个数字依次输入递归函数
            for(int i = 1; i <= (num.length() / 2); ++i) {
                for(int j = 1; j <= (num.length() - i) / 2; ++j) {
                    if(solve(num.substr(0, i), num.substr(i, j), num.substr(i + j)))
                        return true;
                }
            }
            
            return false;
        }
        
        bool solve(string s1, string s2, string num) {
            // 如果两个数字其中有一个包含前缀0,则返回false
            if((s1.length() > 1 && s1[0] == '0') || (s2.length() > 1 && s2[0] == '0'))
                return false;
            // 计算两个数字之和
            string sum = add(s1, s2);
            // 如果两个数字之和与剩余的字符串数字相等,则返回true
            if(sum == num)
                return true;
            // 否则,如果两个数字之和与后续字符串数字不匹配则返回false
            if(sum.length() >= num.length() || sum.compare(num.substr(0, sum.length())) != 0)
                return false;
            // 除了以上各个情况,进入下一层递归
            else
                return solve(s2, sum, num.substr(sum.size()));
        }
        // 计算两个字符串数字的和
        string add(string s1, string s2) {
            string res = "";
            int i = s1.length() - 1, j = s2.length() - 1, carry = 0;
            while(i >= 0 || j >= 0) {
                int x = carry + (i >= 0 ? s1[i--] - '0' : 0) + (j >= 0 ? s2[j--] - '0' : 0);
                res.push_back('0' + x % 10);
                carry = x / 10;
            }
            if(carry)
                res.push_back('0' + 1);
            reverse(res.begin(), res.end());
            
            return res;
        }
    };
  • 相关阅读:
    Extjs 4 生成饼状图的例子
    cocos2d-x 3.0rc2 对于每个包执行情况的重要平台 (超级方便)
    HDOJ 1495 非常可乐 【BFS】
    Android采用HttpClient下载图片
    解决本地访问Android文档是非常慢的问题
    潜在语义分析Latent semantic analysis note(LSA)原理及代码
    你奋斗这么辛苦,这辈子要证明什么?
    Objective-C时间戳转换的转换和时间
    Delphi 线程resume 不能调用Execute
    Delphi 多线程 “尚未调用CoInitialize错误”的解决方法
  • 原文地址:https://www.cnblogs.com/heyn1/p/11163743.html
Copyright © 2011-2022 走看看