求解最大偶和连续子序列长度的代码测试通过,需排查潜在问题
代码问题分析与修正方案
你的代码存在核心逻辑偏离题目要求、未定义行为以及效率低下的问题,下面逐一拆解并给出正确解法:
核心错误:误解题目要求
你编写的代码实际上在寻找从1开始的前缀连续子序列中,和为偶数的最长长度,但题目要求的是原序列中任意连续子序列的最长和为偶数的长度。这导致你的算法完全偏离需求:
- 例如n=2时,原序列的连续子序列包括
[1](和为奇数)、[2](和为偶数)、[1,2](和为奇数),最长符合要求的长度是1,但你的代码会递归到n=0,返回0,完全错误。
代码中的其他问题
1. 递归分支缺少return语句
在Nsum函数的else块中,你调用了Nsum(n-1)但没有返回该值,这会导致函数执行完递归后无明确返回值,属于C语言中的未定义行为,可能返回随机垃圾值。正确写法应为return Nsum(n-1);。
2. 求和效率低下
通过循环累加计算1到n的和,每次递归都重复计算,时间复杂度为O(n²)。实际上可以用数学公式sum = n*(n+1)/2直接计算,时间复杂度降为O(1)。
正确解题思路与代码
思路分析
对于序列{1,2,...,n},寻找最长和为偶数的连续子序列:
- 计算整个序列的总和
S = n*(n+1)/2:- 若
S为偶数:整个序列就是符合要求的最长子序列,长度为n。 - 若
S为奇数:需要去掉一个奇数元素(奇数个奇数相加为奇数,去掉一个后剩余奇数个数为偶数,总和变为偶数),此时最长长度为n-1(唯一例外是n=1,此时无符合要求的非空子序列,返回0)。
- 若
修正后的代码
#include <stdio.h> int maxEvenSubseqLength(int n) { long long sum = (long long)n * (n + 1) / 2; // 用long long避免大数溢出 if (sum % 2 == 0) { return n; } else { return n == 1 ? 0 : n - 1; } } int main(void) { int t, n; scanf("%d", &t); while(t--) { scanf("%d", &n); printf("%d\n", maxEvenSubseqLength(n)); } return 0; }
测试案例验证
- n=1:总和为1(奇数),返回0,正确。
- n=2:总和为3(奇数),返回1,正确(子序列
[2]符合要求)。 - n=3:总和为6(偶数),返回3,正确。
- n=5:总和为15(奇数),返回4,正确(子序列
[2,3,4,5]和为14,偶数)。
内容的提问来源于stack exchange,提问作者Rohan Rathore
相关产品推荐
相关产品推荐

