算法分析之累加数

181 阅读1分钟

题目

一个有效的累加序列必须至少包含3个数。除了最开始的两个数以外,序列中的每个后续数字必须是它之前两个数字之和。现在有一个只包含数字 '0'-'9' 的字符串,编写一个算法来判断给定输入是否是“累加数”。如果是,返回 true ;否则,返回 false

代码实现

public boolean isAdditiveNumber(String num) {
      for (int i = 1; i < num.length(); i++) {
        if (i > 1 && num.charAt(0) == '0') {
          break;
        }
        for (int j = i + 1; j < num.length(); j++) {
          if (j - i > 1 && num.charAt(i) == '0') {
            break;
          }
          Long preNum = Long.parseLong(num.substring(0, i));
          Long curNum = Long.parseLong(num.substring(i, j));
          Long sum = preNum + curNum;
          int end = Long.toString(sum).length() + j;
          int start = j;
          while (end <= num.length() && sum.equals(Long.parseLong(num.substring(start, end)))) {
            preNum = curNum;
            curNum = sum;
            sum = preNum + curNum;
            start = end;
            end = Long.toString(sum).length() + end;
          }
          if (start == num.length()) {
            return true;
          }
        }
      }
      return false;
    }
    

代码分析

从上面的代码我们可分析处理,具体实现思路如下:

  1. 首先使用两个循环遍历字符串 num 中的所有可能的"第一个数和第二个数"的组合,其中第一个数从第一个字符开始,第二个数从第一个数后面字符开始。
  2. 在遍历的过程中,需要注意一些特殊情况。比如,第一个数和第二个数不能包含前导零,如果包含了前导零,就可以直接跳过这个组合。另外,在计算第三个数时,需要将前两个数相加,然后将和与字符串 num 中的一段子串进行比较,如果相等,则将第二个数赋值给第一个数,将和赋值给第二个数,继续计算第三个数。如果一直计算到字符串 num 的末尾,说明这个字符串是加法数列,返回 true
  3. 如果遍历完所有可能的组合都没有找到加法数列,就返回 false

复杂度分析

时间复杂度:O(n^3),n 是 字符串的长度。空间复杂度:O(1)。