划分字符串回溯leetcode题842_282

842. Split Array into Fibonacci Sequence

给一个只有数字的字符串,将它划分成多个子字符串,并且成斐波那契数列。每个数字不能以0开头,除了0本身。

Input: “11235813”
Output: [1,1,2,3,5,8,13]

用回溯法,关键点是

  1. 子字符串可能很长所以转化成long型,并且去掉大于最大值的数
  2. 当列表中数字少于两个时特殊处理,我的方法是设置成负数
  3. 每个数字不能以0开头,所以可以剪枝一下
  4. 最后是在前两个数字还没有确定时,当剩余子字符串的位数少于前面的一半时就剪枝,因为此时前面子字符串相加肯定大于后面的子字符串
public List<Integer> splitIntoFibonacci(String S) {
    List<Integer> res = new ArrayList<>();
    help(S, 0, res, -1, -1);
    return ress;
}

List<Integer> ress = new ArrayList<>();
public void help(String S, int index, List<Integer> seq, long first, long second) {
    if (index == S.length() && seq.size() >= 3) {
        ress = new ArrayList<>(seq);
        return;
    }

    for (int i = index; i < S.length(); i++) {
        if (i > index && S.charAt(index) == '0') break;
        long number = Long.parseLong(S.substring(index, i+1));
        if (number > Integer.MAX_VALUE) break;

        if (first < 0) {
            if (S.length() - i - 1 < i + 1) break;
            seq.add((int)number);
            help(S, i+1, seq, number, -1);
            seq.remove(seq.size()-1);
            first = -1;
        } else if (second < 0) {
            if (S.length() - i - 1 < (i+1) / 2) break;
            seq.add((int)number);
            help(S, i+1, seq, first, number);
            seq.remove(seq.size()-1);
            second = -1;
        } else {
            if (first + second == number) {
                seq.add((int)number);
                help(S, i+1, seq, second, number);
                seq.remove(seq.size()-1);
            } else if (first + second < number)
                break;
        }
    }
}

282. Expression Add Operators

给一个纯数字字符串,在其中添加 + - * 三种运算符使得运算结果等于target。

Input: num = “123”, target = 6
Output: [“1+2+3”, “123”]

还是回溯,三个关键点:

  1. 字符串可能很长,所以用long型
  2. 对0开头的的数剪枝,除了0本身
  3. 比较技巧,进行乘法运算时通过记录上一步运算的第二个数字来使运算优先级正确
public List<String> addOperators(String num, int target) {
    help(num, target, 0, 0, "", 0);
    return res;
}

List<String> res = new ArrayList<>();
public void help(String num, int target, long result, int index, String s, long last) {
    if (index == num.length() && result == target) {
        res.add(s);
        return;
    }

    for (int i = index; i < num.length(); i++) {
        if (i > index && num.charAt(index) == '0') break;

        long v1 = Long.parseLong(num.substring(index, i+1));
        if (index == 0)
            help(num, target, v1, i+1, num.substring(index, i+1), v1);
        else {
            help(num, target, result + v1, i + 1, s + '+' + num.substring(index, i + 1), v1);
            help(num, target, result - v1, i + 1, s + '-' + num.substring(index, i + 1), -v1);
            help(num, target, result - last + last * v1, i + 1, s + '*' + num.substring(index, i + 1), v1 * last);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值