今日训练题:18. 四数之和
总体思路:
先对数组排序,方便双指针移动和去重;
固定两个数(i、j 两层循环);
用左右双指针找剩下两个数,凑成和为 target;
全程去重(避免重复四元组);
提前剪枝(没必要的循环直接跳过)
代码如下:
总结:
1. 为什么要排序?
双指针必须在有序数组上才能工作(和小左移、和大右移);
方便去重(相同数字会挨在一起);
方便剪枝(快速判断最小 / 最大组合)。
2. 为什么要强转long?
int范围有限,四个大数相加会溢出变成负数,导致判断错误。(long)把其中一个数转成长整型,整个加法就会用长整型计算。
3. 四层去重逻辑
i 去重:nums[i] == nums[i-1]跳过;
j 去重:nums[j] == nums[j-1]跳过;
left 去重:找到答案后跳过重复左指针;
right 去重:找到答案后跳过重复右指针。
作用:保证最终结果没有重复的四元组。
4. 四层剪枝(优化效率)
提前判断不可能满足条件的情况,直接跳过 / 退出循环,减少无效计算:
最小四数和 > target → 后面更大,直接退出;
当前 i + 最大三数 < target → i 太小,换下一个;
i+j + 最小两数 > target → 退出;
i+j + 最大两数 < target → j 太小,换下一个。
5. 双指针逻辑
left从 j+1 开始(第三个数);
right从末尾开始(第四个数);
sum < target→ 左指针右移(变大);
sum > target→ 右指针左移(变小);
sum == target→ 记录答案 + 去重 + 移动指针。
题目链接:https://leetcode.cn/problems/4sum/ 视频讲解:https://www.bilibili.com/video/BV1DS4y147US