2026-03-04:最长斐波那契子数组。用go语言,给定一个只包含正整数的数组 nums。把数组中任意一段连续元素看作一个片段;如果该片段从第 3 个元素起,

0 阅读5分钟

2026-03-04:最长斐波那契子数组。用go语言,给定一个只包含正整数的数组 nums。把数组中任意一段连续元素看作一个片段;如果该片段从第 3 个元素起,每一项都等于前面两项之和,则称其为斐波那契型片段。长度为 1 或 2 的片段默认满足这个条件。请找出 nums 中满足该性质的最长连续片段,并返回它的长度。

3 <= nums.length <= 100000。

1 <= nums[i] <= 1000000000。

输入: nums = [1,1,1,1,2,3,5,1]。

输出: 5。

解释:

最长的斐波那契子数组是 nums[2..6] = [1, 1, 2, 3, 5]。

[1, 1, 2, 3, 5] 是斐波那契的,因为 1 + 1 = 2, 1 + 2 = 3, 且 2 + 3 = 5。

题目来自力扣3708。

一、需求理解

你希望我基于给定的Go语言代码,详细拆解它解决“最长斐波那契子数组”问题的核心思路和执行过程,并分析该解法的时间复杂度与空间复杂度。

二、代码执行过程分步解析

我们以输入 nums = [1,1,1,1,2,3,5,1] 为例,逐步拆解代码的执行逻辑:

步骤1:初始化核心变量

  • 首先获取数组长度 n = 8(数组有8个元素)。
  • 初始化 ans = 2:因为题目规定长度为1或2的片段默认满足条件,所以最长长度的初始值设为2(最小有效长度)。
  • 初始化 start = 0start 是当前斐波那契型片段的起始下标,用于标记当前有效片段的起点。

步骤2:遍历数组验证斐波那契规则(核心循环)

循环从 i = 2 开始(因为需要验证第3个元素是否满足“前两项之和”的规则),直到 i < n

i值nums[i]nums[i-1]+nums[i-2]比较结果执行逻辑ans值start值说明(当前有效片段)
211+1=2不相等1. ans = max(2, 2-0)=2;2. start = 2-1=121原片段[0,1]无效,新起点设为1
311+1=2不相等1. ans = max(2, 3-1)=2;2. start = 3-1=222原片段[1,2]无效,新起点设为2
421+1=2相等无操作22片段[2,3,4]有效,继续
531+2=3相等无操作22片段[2,3,4,5]有效,继续
652+3=5相等无操作22片段[2,3,4,5,6]有效,继续
713+5=8不相等1. ans = max(2, 7-2)=5;2. start = 7-1=656原片段[2,6]有效(长度5),更新ans;新起点设为6

步骤3:处理最后一段未验证的有效片段

循环结束后,需要检查最后一段从 start 到数组末尾的片段是否为有效片段: 执行 return max(ans, n-start),即 max(5, 8-6)=max(5,2)=5,最终返回结果5。

步骤4:关键逻辑补充说明

  • nums[i] != nums[i-1]+nums[i-2] 时:说明当前位置 i 不满足规则,因此start 为起点到 i-1 的片段 是当前最长的有效斐波那契片段,需要计算其长度(i-start)并更新 ans;同时将 start 重置为 i-1(因为 i-1i 可能是新片段的前两个元素,符合默认有效规则)。
  • nums[i] == nums[i-1]+nums[i-2] 时:说明当前片段仍满足规则,无需更新 ansstart,继续向后验证。

三、复杂度分析

1. 时间复杂度

  • 核心逻辑是一次遍历数组:循环从 i=2i=n-1,共执行 n-2 次,每次循环内的操作(比较、取最大值、赋值)都是 O(1) 的常数时间。
  • 最终的 max 操作也是 O(1)
  • 因此,总的时间复杂度为 O(n)n 是数组长度),满足题目中 n <= 100000 的性能要求。

2. 额外空间复杂度

  • 代码中仅使用了有限的几个变量(nansstarti),没有创建额外的数组、哈希表等数据结构,所有变量占用的空间与输入数组长度无关。
  • 因此,总的额外空间复杂度为 O(1)(常数级空间)。

总结

  1. 核心思路:通过滑动窗口(双指针) 思想,用 start 标记当前有效片段起点,遍历验证每个位置是否满足斐波那契规则,不满足时更新最长长度并重置起点,最终得到最长有效片段长度。
  2. 关键操作:循环中仅验证“当前元素是否等于前两项之和”,保证了线性时间复杂度;仅使用常数变量,空间复杂度最优。
  3. 复杂度结论:时间复杂度 O(n),额外空间复杂度 O(1)

Go完整代码如下:

package main

import (
	"fmt"
)

func longestSubarray(nums []int) int {
	n := len(nums)
	ans := 2
	start := 0
	for i := 2; i < n; i++ {
		if nums[i] != nums[i-1]+nums[i-2] {
			ans = max(ans, i-start) // [start,i-1] 是斐波那契子数组
			start = i - 1
		}
	}
	return max(ans, n-start) // [start,n-1] 是斐波那契子数组
}

func main() {
	nums := []int{1, 1, 1, 1, 2, 3, 5, 1}
	result := longestSubarray(nums)
	fmt.Println(result)
}

在这里插入图片描述

Python完整代码如下:

# -*-coding:utf-8-*-

def longest_subarray(nums):
    n = len(nums)
    ans = 2
    start = 0
    
    for i in range(2, n):
        if nums[i] != nums[i-1] + nums[i-2]:
            ans = max(ans, i - start)  # [start,i-1] 是斐波那契子数组
            start = i - 1
    
    return max(ans, n - start)  # [start,n-1] 是斐波那契子数组

def main():
    nums = [1, 1, 1, 1, 2, 3, 5, 1]
    result = longest_subarray(nums)
    print(result)

if __name__ == "__main__":
    main()

在这里插入图片描述

C++完整代码如下:

#include <iostream>
#include <vector>
#include <algorithm>

int longestSubarray(std::vector<int>& nums) {
    int n = nums.size();
    int ans = 2;
    int start = 0;

    for (int i = 2; i < n; i++) {
        if (nums[i] != nums[i-1] + nums[i-2]) {
            ans = std::max(ans, i - start);  // [start,i-1] 是斐波那契子数组
            start = i - 1;
        }
    }

    return std::max(ans, n - start);  // [start,n-1] 是斐波那契子数组
}

int main() {
    std::vector<int> nums = {1, 1, 1, 1, 2, 3, 5, 1};
    int result = longestSubarray(nums);
    std::cout << result << std::endl;
    return 0;
}

在这里插入图片描述