通过双指针将时间复杂度降一个级别。
public class TOP {//15. 三数之和public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> res = new ArrayList<>();int n = nums.length;if (n < 3) {return res;}Arrays.sort(nums);//先确定一个值,再用双指针找另外两个,并去重for (int i = 0; i < n; i++) {//去除无效值if (nums[i] > 0) break;//第一个数字去重if (i > 0 && nums[i] == nums[i - 1]) continue;int left = i + 1;int right = n - 1;//双指针计算另外两个数字while (left < right) {int sum = nums[i] + nums[left] + nums[right];//不满足条件,缩小窗口if (sum > 0) {right--;} else if (sum < 0) {left++;} else {//找到一个结果res.add(Arrays.asList(nums[i], nums[left], nums[right]));//对另外两个数字去重while (left < right && nums[left] == nums[left + 1]) left++;while (left < right && nums[right] == nums[right - 1]) right--;left++; //移动到不重复区right--;}}}return res;}//18. 四数之和public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> res = new ArrayList<>();int n = nums.length;if (nums.length < 4) {return res;}//排序来剪枝Arrays.sort(nums);//先确定2个值,再用双指针找另外两个,并去重for (int i = 0; i < n; i++) {//去除无效值 (也可以排除[1000000000,1000000000,1000000000,1000000000]溢出情况)if (nums[i] > 0 && nums[i] > target) break;//第一个数字去重if (i > 0 && nums[i] == nums[i - 1]) continue;for (int j = i + 1; j < n; j++) {//第2个数字去重if (j > i + 1 && nums[j] == nums[j - 1]) continue;int left = j + 1;int right = n - 1;//双指针计算另外两个数字while (left < right) {//防止int溢出long sum = nums[i] + nums[j] + nums[left] + nums[right];//不满足条件,缩小窗口if (sum > target) {right--;} else if (sum < target) {left++;} else {//找到一个结果res.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));//对另外两个数字去重while (left < right && nums[left] == nums[left + 1]) left++;while (left < right && nums[right] == nums[right - 1]) right--;left++;right--;}}}}return res;}
}