• [Leetcode] 第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)情况非常多,采用回溯的方法
    2)特殊情况:以0为开头的非零整数;特大数long  long

    3)具体解析请看代码注释

    三、实现代码

     1 class Solution {
     2 public:
     3     bool isAdditiveNumber(string num) {
     4         int n = num.size();
     5         if (n < 3)return false;
     6         long long ppre = 0, pre = 0;
     7         //找出第一个数和第二个数
     8         for (int i = 1; i <= n / 2; ++i) {//第一个数的长度不能超过n/2
     9             ppre = stoi(num.substr(0, i));
    10             for (int j = 1; i + j <= (n * 2) / 3; ++j) {//第一个和第二个数总的长度不能超过2/3
    11                 pre = stoi(num.substr(i, j));//从位置i开始截取
    12                 if (dfs(i + j, max(i, j), pre, ppre, num))return true;//第二个数不一定比第一个数大
    13             }
    14         }
    15         return false;
    16     }
    17 private:
    18     /**
    19     * 计算当前的数是不是前两个数的和
    20     * pos代表当前指针达到的位置
    21     * len代表要截取的长度
    22     * pre代表前面的数
    23     * ppre代表前一个的前一个数
    24     * s代表字符串
    25     */
    26     bool dfs(int pos, int len, long long pre, long long ppre, string &s) {
    27         int n = s.size();
    28         if (pos == n)return true;//已经计算到最后了
    29         bool flag = false;
    30         long long cur = 0;
    31         for (int i = len; pos + i <= n; ++i) {
    32             cur = stoi(s.substr(pos, i));
    33             if (cur > pre + ppre)break;//当前的数大于两者之和,就跳出循环,不能再截取更长的长度了
    34             if (cur < pre + ppre)continue;//如果当前的数小于两者之和,就截取更长的一位
    35             flag = dfs(pos + i, i, cur, pre, s);//对当前来说两者相等,继续检验,下一次的开始长度至少和前面一个一样
    36             if (flag)break;//只要找到一个,就可以跳出了
    37         }
    38         return flag;
    39     }
    40     /**
    41     * 把字符串转换成整数
    42     */
    43     long long stoi(const string &s) {
    44         if (s.size() > 1 && s[0] == '0')return -1;
    45         stringstream ss(s);
    46         long long res;
    47         ss >> res;
    48         return res;
    49     }
    50 
    51 };

    需要注意的地方有:第8行和第10行的等号;第43行的const

  • 相关阅读:
    2020/11/06 模拟赛 T1
    2020/11/04 模拟赛 圆与圆之间的距离是不能一概而论的
    2020/11/04 模拟赛 经典字符串问题
    2020/11/03 模拟赛 偶数
    2020/11/03 模拟赛 斐波
    LG P7078 贪吃蛇
    js类和对象,继承(6中方式)
    js类和对象,继承(class语法题)
    网站
    品优购项目1- iconfont使用教程:
  • 原文地址:https://www.cnblogs.com/zhizhiyu/p/10190438.html
Copyright © 2020-2023  润新知