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.

 

Example 1:

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

Example 2:

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

 

Constraints:

  • num consists only of digits '0'-'9'.
  • 1 <= num.length <= 35

Follow up:
How would you handle overflow for very large input integers?

Rust Solution

struct Solution;

impl Solution {
    fn is_additive_number(num: String) -> bool {
        let n = num.len();
        let mut res = false;
        let mut cur: Vec<u64> = vec![];
        Self::dfs(0, &mut cur, &mut res, &num[0..n], n);
        res
    }

    fn dfs(start: usize, cur: &mut Vec<u64>, valid: &mut bool, s: &str, n: usize) {
        if start == n {
            if cur.len() >= 3 {
                *valid = true;
            }
        } else {
            for i in start + 1..=n {
                if &s[start..=start] == "0" && i - start > 1 {
                    return;
                }
                if let Ok(x) = s[start..i].parse::<u64>() {
                    let k = cur.len();
                    if k < 2 {
                        cur.push(x);
                        Self::dfs(i, cur, valid, s, n);
                        cur.pop();
                    } else {
                        if cur[k - 1] + cur[k - 2] == x {
                            cur.push(x);
                            Self::dfs(i, cur, valid, s, n);
                            cur.pop();
                        }
                    }
                }
            }
        }
    }
}

#[test]
fn test() {
    let num = "112358".to_string();
    let res = true;
    assert_eq!(Solution::is_additive_number(num), res);
    let num = "199100199".to_string();
    let res = true;
    assert_eq!(Solution::is_additive_number(num), res);
    let num = "101".to_string();
    let res = true;
    assert_eq!(Solution::is_additive_number(num), res);
    let num = "12012122436".to_string();
    let res = true;
    assert_eq!(Solution::is_additive_number(num), res);
    let num = "121474836472147483648".to_string();
    let res = true;
    assert_eq!(Solution::is_additive_number(num), res);
}

Having problems with this solution? Click here to submit an issue on github.