问题:
解:
class Solution { /** * 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ? * 找出所有满足条件且不重复的三元组。 * 双指针法, * 首先,将数组nums排序,循环整个数组 * 在num[i]后定义左右两个指正,left=i+1,right=len-1 * 1)如果nums[i] 大于零的话,那么三个数相加一定大于0,终止循环, * 2)如果nums[i] == nums[i - 1],则代表该值已经判断过,跳过该值 * 3)当三个数和等于0时,如果nums[left] == nums[left + 1],会导致数据重复,跳过该值,记录右侧的值为结果 * 4)当三个数和等于0时,如果nums[right] == nums[right - 1],会导致数据重复,跳过该值,记录左侧的值为结果 * * @param nums * @return */ public List<List<Integer>> threeSum(int[] nums) { List<List<Integer>> res = new ArrayList<>(); if (nums == null || nums.length < 3) { return res; } //先将数组排序 quickSort(nums, 0, nums.length - 1); // 双指针法 for (int i = 0; i < nums.length && nums[i] <= 0; i++) { int left = i + 1; int right = nums.length - 1; if (i > 0 && nums[i] == nums[i - 1]) { continue; } while (left < right) { int sum = nums[i] + nums[left] + nums[right]; if (sum == 0) { List<Integer> list = new ArrayList<>(); list.add(nums[i]); list.add(nums[left]); list.add(nums[right]); res.add(list); while (left < right && nums[left] == nums[left + 1]) { left++; } while (left < right && nums[right] == nums[right - 1]) { right--; } left++; right--; } else if (sum < 0) { left++; } else { right--; } } } return res; } /** * 快排nums数组 * * @param arr * @param left * @param right * @return */ public void quickSort(int[] arr, int left, int right) { //递归终止条件 if (left > right) { return; } int base = arr[left]; int l = left; int r = right; while (l != r) { while (l < r && arr[r] >= base) { r--; } while (l < r && arr[l] <= base) { l++; } if (l < r) { swap(arr, r, l); } } swap(arr, left, l); quickSort(arr, left, l - 1); quickSort(arr, l + 1, right); } /** * 交换两个数 * * @param arr * @param r * @param l */ private void swap(int[] arr, int r, int l) { int temp = arr[r]; arr[r] = arr[l]; arr[l] = temp; } }