LeetCode每日一题——12.8将数组拆分成斐波那契序列


题目描述

给定一个数字字符串 S,比如 S = “123456579”,我们可以将它分成斐波那契式的序列 [123, 456, 579]。

形式上,斐波那契式序列是一个非负整数列表 F,且满足:

0 <= F[i] <= 2^31 - 1,(每个整数都符合 32 位有符号整数类型);
F.length >= 3;
对于所有的0 <= i < F.length - 2,都有 F[i] + F[i+1] = F[i+2] 成立。
将字符串拆分成小块时,每个块的数字一定不要以零开头,除非这个块是数字 0 本身。

返回从 S 拆分出来的任意一组斐波那契式序列,不能拆分则返回 []。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/split-array-into-fibonacci-sequence

思路

  1. 回溯:
  • 声明一个数组来保存回溯过程(遍历字符串中所有可能的当前被拆分的数字情况,再继续拆分剩余字符串)中满足条件的数。满足以下条件时将数字保存进数组

    (1)若数组为空或者数字个数为1,则直接保存进数组

    (2)若数组数字个数大于等于2,则新拆分的数等于数组最后看两个数的和时,将新拆分的数保存进数组

  1. 剪枝:
  • 以下情况可以直接停止此次拆分:

    (1)新拆分的数若以‘0’开头,且不是0

    (2)新拆分的数超过2^31-1

    (3)数组数字个数大于等于2,则新拆分的数大于数组最后看两个数的和

代码(CPP)

#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Solution {
	vector<int> res;
public:
	vector<int> splitIntoFibonacci(string S) {
		back(S, 0, 0, 0);
		return res;

	}

	bool back(string S, int sum, int pre, int index) {
		//结束回溯
		if (index == S.length()) {
			bool hasRes = (res.size() >= 3);
			return hasRes;
		}
		//当前的数字,声明为long检测int溢出
		long curNum = 0;
		for (int i = index; i < S.length(); i++) {
			//检测溢出
			curNum = curNum * 10 + S[i] - '0';
			if (curNum > INT_MAX) {
				return false;
			}
			//以'0'开头的新数字只能是0
			if (S[index] == '0' && i != index) {
				return false;
			}
			if (res.size() >= 2) {
				//当前的数字比其前两个数字的和大,不满足;小则继续增添该数
				if (curNum > sum) {
					return false;
				}
				else if(curNum < sum){
					continue;
				}
			}
			//当前的数字比其前等于两个数字的和或者当前答案数组中的数字个数小于2,将其加入答案数组
			res.push_back(((int)curNum));
			if (back(S, curNum + pre, curNum, i + 1)) {
				return true;
			}
			res.pop_back();
		}
		return false;
	}
};

int main() {
	string S = "123456579";
	Solution* s = new Solution();
	vector<int> res = s->splitIntoFibonacci(S);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值