有序数组两数之和配对统计代码中的while死循环问题排查
问题分析:死循环的核心原因
你的代码陷入死循环的问题非常直观——当找到一组满足a[i] + a[j] == k的配对后,你没有移动任何一个指针(i或j)。
举个具体的例子:假设输入的k=6,此时a[0]+a[4]=1+5=6,程序会执行ct++,但执行完之后i还是0,j还是4,i<j的条件依然成立。下一轮循环又会重复判断这对元素,无限执行ct++,永远跳不出循环。
修复方案
针对有序数组的两数配对统计,找到符合条件的配对后,必须移动指针来避免重复判断同一对元素。根据你的需求,这里提供两种常见的处理方式:
方式一:适配无重复元素的数组(你的示例场景)
如果数组中没有重复元素,找到配对后同时移动i和j就能解决问题:
#include<bits/stdc++.h> using namespace std; int main() { int a[5] = {1, 2, 3, 4, 5}; int k; cin >> k; int i = 0, j = 4, ct = 0; while (i < j) { if (a[i] + a[j] > k) { --j; } else if (a[i] + a[j] < k) { ++i; } else { ct++; // 关键:找到配对后同时移动两个指针,避免重复判断 ++i; --j; } } cout << ct; }
方式二:适配包含重复元素的数组(通用场景)
如果数组中有重复元素(比如a = [1,1,2,2,3],k=3),需要跳过重复元素避免统计重复配对:
#include<bits/stdc++.h> using namespace std; int main() { vector<int> a = {1,1,2,2,3}; int k; cin >> k; int i = 0, j = a.size()-1, ct = 0; while (i < j) { int sum = a[i] + a[j]; if (sum > k) { --j; } else if (sum < k) { ++i; } else { ct++; // 跳过i指针指向的重复元素 while (i < j && a[i] == a[i+1]) ++i; // 跳过j指针指向的重复元素 while (i < j && a[j] == a[j-1]) --j; // 移动到下一组可能的配对 ++i; --j; } } cout << ct; }
额外优化提示
原代码中你单独声明i,j,ct再赋值,其实可以直接在定义时初始化,让代码更简洁。另外,使用vector代替固定大小的数组,能让代码更灵活,适配不确定长度的输入场景。
内容的提问来源于stack exchange,提问作者PANKAJ kUmaR
相关产品推荐
相关产品推荐

