leetcode 306 类加数(递归)

1. 题目:https://leetcode-cn.com/problems/additive-number

2. 思路:

假如我有一个函数,dfs(int pos, long long pre1, long long pre2),它能够告诉我,已经前两个数字分别是pre1, pre2,从给定字符串的pos位开始,是否存在一个序列满足
题目要求,如果满足,返回true给我,否则返回false给我。
于是,我可以在主函数中从字符串的前i位中取出第一个数字pre1,从i~j位取出第二个数字pre2,然后调用dfs(j+1, pre1, pre2),一旦有一次dfs返回true, 说明该
取法满足题意,即得到最后答案=true。如果i遍历完了所有的位置,还没有找到一种满足的方案,则返回最后结果false.

3. 需要注意的地方:

3.1 字符串长度 [1, 35],所以存放数字需要用long long八字节类型整数,不能用int。

3.2 每个数字都不能有前缀0

4. 代码:

typedef long long ll;

int len;

char* num;

// bool dfs(int pos, ll pre1, ll pre2)

// 此递归函数表示:已经前两个数字分别为pre1, pre2,从字符串的pos位开始,是否满足题目要求的。

// 满足则返回true, 否则返回false。

bool dfs(int pos, ll pre1, ll pre2) {

    // 1. cur表示当前我们寻找的"第三个数"

    ll cur = 0;

    // 2. 确定cur的最大下标范围

    int index1 = len;

    if (num[pos] == '0') { //如果首位是0,那么cur只能是0,因为题目要求任何数字都不能有前缀0

        index1 = pos+1;

    }

    for(int i=pos; i<index1; i++) {

        cur = cur*10+num[i]-'0';

        if (pre1 + pre2 == cur) {            

            // 如果正好读完了整个字符串,或者 从字符串的i+1位开始是否能找到可以满足题意的情况

            if (i+1 == len || dfs(i+1, pre2, cur)) {

                return true;

            }

        } else if (pre1 + pre2 < cur) { //如果前两个数字的和 已经小于当前的数字,则无需继续循环,因为cur只会越来越大。

            return false;

        }

    }

    // 如果前两个数字的和 始终大于cur,说明无法找到下一个数字 = pre1+pre2

    return false;

}

bool isAdditiveNumber(char * num2){

    ll max(ll a, ll b);

    // 1. 设置全局变量,给递归函数用,set global variables for recursive method.

    len = strlen(num2);

    num = num2;

    // 2. 手工先取出 前两个数字

    ll pre1=0, pre2=0;

    // index1表示第一个数字的最后一位下标,index2表示第二个数字最后一位的下标。

    int index1 = 0, index2 = 0;

    // 2.1 第一个数字的下标范围

    if (num[0] == '0') {

        index1 = 1; //

    } else {

        index1 = len/2; // 第一个数字的长度必然<len/2

    }

    // 2.2 设置第一个数字

    for (int i=0; i<index1; i++) {

        pre1 = pre1*10+num[i]-'0';

        pre2 = 0;

        // 2.3 第二个数字的下标范围

        int j = i+1;

        if (num[j] == '0') {

            index2 = i+1;

        } else {

            index2 = len-2; // 至少留一个位给下一个数

        }

        // 2.4 设置第二个数字

        for (; j<=index2; j++) {

            pre2 = pre2*10+num[j]-'0';

            // 判断从j+1位开始,是否能够找到后序的满足题意的情况。

            if (dfs(j+1, pre1, pre2)) {

                return true;

            }

        }

    }

    return false;

}

ll max(ll a, ll b) {

    return a>b?a:b;

}

上一篇:的回复打电话给


下一篇:分享一个简单的爬虫案例