LeetCode每日一题,18. 4 Sum
先看题目描述
大意就是给定一个整数数组 nums 和一个目标数 target,让我们返回 nums 数组中相加等于 target 的所有四元组,返回的 list 中不能出现重复元素
算法和思路
四数之和与之前做的三数之和的思路基本是一致的,其实就是在三数之和的基础上加了个遍历的指针
使用四个指针,i < j < left < right,i 和 j 指针用于 nums 数组的两层循环,每次循环时,固定最小的 i 和 j 指针在左边,left = i + 1,right = len - 1,移动 left 和 right 指针包夹求解,计算 sum = nums[i] + nums[j] + nums[left] + nums[right],当 sum = target 时,保存这个解,并同时移动 left 和 right 指针;当 sum < target 时,说明偏小,left右移;当 sum > target 时,说明偏大,right 左移。当 left 和 right 相遇时,则代表以当前 i 和 j 为最小值的的解已经全部求得,则进入下一轮循环
注意:因为要使用双指针的 方法,必须先做个排序
重复解的处理:重复解的出现是因为有重复数字的情况,所以每次移动指针时需要确保指针对应的数字发生了改变
算法源码
1 | import java.util.*; |
注意这两个语句
1 | if (num1 + num2 + nums[left] + nums[left + 1] > target) break; |
原本提交的代码是没有这两个语句的,运行效率一般,看了击败效率排在前列的代码后,将这两条语句添加了上去,运行效率改善了很多。第一个语句代表以当前 i 和 j 为最小值的四元组的最小和都大于 target,那么就跳出内层循环,移动 i 指针进行下一轮的外层循环;第二个语句代表以当前 i 和 j 为最小值的四元组的最大和都大于 target,那么就直接移动 j 指针进行下一轮的内层循环