[Backtracking] [leetcode] accumulative number

topic:

The accumulative number is a string, and the numbers that make up it can form an accumulative sequence.

A valid accumulation sequence must contain at least 3 numbers. Except for the first two numbers, the other numbers in the string are equal to the sum of the two previous numbers.

Given a string containing only the numbers '0'-'9', write an algorithm to determine whether the given input is an accumulative number.

Explanation: The number in the accumulation sequence will not start with 0, so 1, 2, 03 or 1, 02, 3 will not appear.

Example 1:

Input: "112358"
Output: true 
Explanation: The accumulation sequence is: 1, 1, 2, 3, 5, 8. 1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8
Example 2:

Input: "199100199"
Output: true 
Explanation: The cumulative sequence is: 1, 99, 100, 199. 1 + 99 = 100, 99 + 100 = 199
Advanced:
How do you deal with an overflowing integer input?

source:

306. Cumulative number

Problem-solving ideas: backtracking

This question is similar to splitting a number string into a Fibonacci sequence , except that this question returns the bool type and the number is very large.

Define an array path to record the number of splits.

  • Recursive termination condition: the string split is completed and at least 3 numbers are split
  • Pruning conditions: when one is completed, or when the first number is put in, if its length exceeds half of the string, it must not be split, or when the sum of the first two numbers is less than the current number n.
class Solution {
public:
    vector<long> path;
    bool finish;
    bool isAdditiveNumber(string S) {
        finish = false;
        // 处理开头的0
        int start = 0;
        while (start < S.size() && S[start] == '0') {
            path.push_back(0);
            start++;
        }
        back(S, start);
        return finish;
    }
    void back(const string& s, int start) {
        if (path.size() > 2 && start == s.size()) {
            finish = true;
            return;
        }
 
        // 处理开头的0
        if (s[start] == '0') {
            if (path.size() < 2) {
                path.push_back(0);
                back(s, start + 1);
                path.pop_back();
            }
            return;
        }
        long n = 0;
        for (int i = start; i < s.size(); i++) {
            if (finish) break;
            int sz = path.size();
            if ((sz == 0  && i >= s.size()/2) ||
                (sz > 1 && path[sz-1] + path[sz-2] < n)) break;
            n = n * 10 + s[i] - '0'; // n:[start,i]内的数字
            if (sz < 2 || path[sz-1] + path[sz-2] == n) {
                path.push_back(n);
                back(s, i + 1);
                path.pop_back();
            }
        }
    }
};

 

Guess you like

Origin blog.csdn.net/hbuxiaoshe/article/details/115250659