[Leetcode][015] 3Sum (Java)
题目在这里: https://leetcode.com/problems/3sum/
【标签】 Array; Two Pointers
【个人分析】
老实交待,这个题卡半天,第一次做不会,抄别人的。过了很久,第二次做,还是不会……。好几次都是Time Limited Error。在看过正确答案之后,才知道是用的Two Pointers + sort 做的优化。
怎么优化? 简单说,就是通过 排序 + 跳过重复(利用Two Pointers) 来达到题目中避免 duplicates的要求。
核心思路: 我们给最终的由3个数组成的小数组叫 triplet。
1. 先锁定triplet中的第一个数字的index为 i (Line 12),
2. 然后我们希望从 [ nums[i + 1], nums[end]] 中找到两个数字,使得两个数字的和为 (0 - nums[i])
关键步骤:1. 在锁定第一个数字index的时候,跳过所有重复的数字 (Line 16处)。直到我们找到下一个不重复的数字作为triplet中的第一个数字
2. 在从[nums[i + 1], nums[end]]中找两个数字的时候,利用left pointer, right pointer。如果 left, right两个数的和比 twoSumTarget (Line 39)
小的话,只能通过将left pointer向右移动,来使得left + right的和更大一些,从而更接近twoSumTarget。
【一点心得】
在O(N^2)的算法中,考虑加入O(NlgN) 的排序操作。特别是遇到需要去除重复的时候,利用排序 + Two Pointers 来达到 HashSet的效果。
1 public class Solution { 2 public List<List<Integer>> threeSum(int[] nums) { 3 List<List<Integer>> result = new ArrayList<List<Integer>>(); 4 int len = nums.length; 5 if (len < 3) { 6 return result; 7 } 8 9 Arrays.sort(nums); 10 11 // for all number that can be the 1st number of triplet 12 for (int i = 0; i < len - 1; i++) { 13 int firstNumber = nums[i]; 14 15 // skip all duplicated first number 16 if (i == 0 || firstNumber != nums[i - 1]) { 17 18 int leftIndex = i + 1; 19 int rightIndex = len - 1; 20 int twoSumTarget = 0 - firstNumber; 21 22 // try to find two numbers that sum up to twoSumTarget 23 while (leftIndex < rightIndex) { 24 int twoSum = nums[leftIndex] + nums[rightIndex]; 25 if (twoSum == twoSumTarget) { 26 // one valid triplet found!! 27 result.add(Arrays.asList(firstNumber, nums[leftIndex], nums[rightIndex])); 28 // skip duplicated nums[leftIndex] 29 while (leftIndex < rightIndex && nums[leftIndex] == nums[leftIndex + 1]) { 30 leftIndex++; 31 } 32 // skip duplicated nums[rightIndex] 33 while (leftIndex < rightIndex && nums[rightIndex] == nums[rightIndex - 1]) { 34 rightIndex--; 35 } 36 // move to next non-duplicates 37 leftIndex++; 38 rightIndex--; 39 } else if (twoSum < twoSumTarget) { 40 // move left towards right to 41 // make twoSum larger to get closer to twoSumTarget 42 leftIndex++; 43 } else { 44 rightIndex--; 45 } 46 } 47 48 } 49 } 50 51 return result; 52 } 53 }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。