LeetCode刷题系列(十五)Sums && Sort Colors
2016-07-06 12:05
453 查看
本篇包含关于2-sum、3-sum等关于给定和,求其中的数的题型,还有包含使用了3sum中前后指针的sort题型。
2 Sum
给定目标值,求数组中和为目标值的两个数。使用一个hash可以巧妙地将时间复杂度降到O(n),之后的题可以参考此思路。public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> hash = new HashMap<Integer, Integer> (); int[] result = new int[2]; for (int i = 0; i < nums.length; ++i) { if (hash.containsKey(target - nums[i])) { result[0] = hash.get(target - nums[i]) + 1; result[1] = i + 1; break; } hash.put(nums[i], i); } return result; }
3 Sum
求数组中和为0的三个数。这道题在2Sum的基础上,在寻找第三个数时,使用left和right两个指针,类似于二分查找,可以有效减少算法时间。这种方法可以移植到接下来介绍的几道题上。public ArrayList<ArrayList<Integer>> threeSum(int[] num) { ArrayList<ArrayList<Integer>> rst = new ArrayList<ArrayList<Integer>>(); if(num == null || num.length < 3) { return rst; } Arrays.sort(num); for (int i = 0; i < num.length - 2; i++) { if (i != 0 && num[i] == num[i - 1]) { continue; // to skip duplicate numbers; e.g [0,0,0,0] } int left = i + 1; int right = num.length - 1; while (left < right) { int sum = num[left] + num[right] + num[i]; if (sum == 0) { ArrayList<Integer> tmp = new ArrayList<Integer>(); tmp.add(num[i]); tmp.add(num[left]); tmp.add(num[right]); rst.add(tmp); left++; right--; while (left < right && num[left] == num[left - 1]) { // to skip duplicates left++; } while (left < right && num[right] == num[right + 1]) { // to skip duplicates right--; } } else if (sum < 0) { left++; } else { right--; } } } return rst; }
4 Sum
求数组中和为目标值的四个数。基本可以使用3sum的方法,在其基础上多加一个for循环(这个无可避免)。public ArrayList<ArrayList<Integer>> fourSum(int[] num, int target) { ArrayList<ArrayList<Integer>> rst = new ArrayList<ArrayList<Integer>>(); Arrays.sort(num); for (int i = 0; i < num.length - 3; i++) { if (i != 0 && num[i] == num[i - 1]) { continue; } for (int j = i + 1; j < num.length - 2; j++) { if (j != i + 1 && num[j] == num[j - 1]) continue; int left = j + 1; int right = num.length - 1; while (left < right) { int sum = num[i] + num[j] + num[left] + num[right]; if (sum < target) { left++; } else if (sum > target) { right--; } else { ArrayList<Integer> tmp = new ArrayList<Integer>(); tmp.add(num[i]); tmp.add(num[j]); tmp.add(num[left]); tmp.add(num[right]); rst.add(tmp); left++; right--; while (left < right && num[left] == num[left - 1]) { left++; } while (left < right && num[right] == num[right + 1]) { right--; } } } } } return rst; }
3 Sum Closest
求数组中和最接近目标值的3个数。这道题与3sum类似,使用其思路,将判别标准改变即可。public int threeSumClosest(int[] numbers, int target) { if (numbers == null || numbers.length < 3) { return -1; } Arrays.sort(numbers); int bestSum = numbers[0] + numbers[1] + numbers[2]; for (int i = 0; i < numbers.length; i++) { int start = i + 1, end = numbers.length - 1; while (start < end) { int sum = numbers[i] + numbers[start] + numbers[end]; if (Math.abs(target - sum) < Math.abs(target - bestSum)) { bestSum = sum; } if (sum < target) { start++; } else { end--; } } } return bestSum; }
Sort Colors
将color号为0、1、2的数依次排序为0***1***2***。与3sum类似,使用两个指针,为1时不动,为0或3时进行交换即可。public void sortColors(int[] a) { if (a == null || a.length <= 1) { return; } int pl = 0; int pr = a.length - 1; int i = 0; while (i <= pr) { if (a[i] == 0) { swap(a, pl, i); pl++; i++; } else if(a[i] == 1) { i++; } else { swap(a, pr, i); pr--; } } } private void swap(int[] a, int i, int j) { int tmp = a[i]; a[i] = a[j]; a[j] = tmp; }
Sort Colors II
这道题color号为从1到k。基于上题的思路,我们可以一次排序2个数,最前面(上题的0)和最后面(上题的2)的,其余看成上题的1,然后依次向中心收缩。public void sortColors2(int[] colors, int k) { int count = 0; int start = 0; int end = colors.length-1; while (count < k) { int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; for (int i = start; i <= end; i++) { min = Math.min(min, colors[i]); max = Math.max(max, colors[i]); } int left = start; int right = end; int cur = left; while(cur <= right) { if (colors[cur] == min) { swap(left, cur, colors); cur++; left++; } else if (colors[cur] > min && colors[cur] < max) { cur++; } else { int tmp = colors[cur]; swap(cur, right, colors); right--; } } count += 2; start = left; end = right; } } void swap(int left, int right, int[] colors) { int tmp = colors[left]; colors[left] = colors[right]; colors[right] = tmp; }
Sort Letters by Case
这道题也是使用前后指针然后交换的思路。public void sortLetters(char[] chars) { int i = 0, j = chars.length - 1; char tmp ; while ( i <= j) { while (i <= j && Character.isLowerCase(chars[i]) ) i++; while (i <= j && Character.isUpperCase(chars[j]) ) j--; if (i <= j) { tmp = chars[i]; chars[i] = chars[j]; chars[j] = tmp; i++; j--; } } //write your code here return ; }
相关文章推荐
- leetcode 179 Largest Number
- leetcode 24 Swap Nodes in Pairs
- leetcode 2 Add Two Numbers 方法1
- leetcode 2 Add Two Numbers 方法2
- leetcode----Longest Substring Without Repeating Characters
- [LeetCode]47 Permutations II
- [LeetCode]65 Valid Number
- [LeetCode]123 Best Time to Buy and Sell Stock III
- [LeetCode] String Reorder Distance Apart
- [LeetCode] Sliding Window Maximum
- [LeetCode] Find the k-th Smallest Element in the Union of Two Sorted Arrays
- [LeetCode] Determine If Two Rectangles Overlap
- [LeetCode] A Distance Maximizing Problem
- leetcode_linearList
- leetcode_linearList02
- 021-Merge Two Sorted Lists(合并两个排好序的单链表);leetcode
- LeetCode[Day 1] Two Sum 题解
- LeetCode[Day 2] Median of Two Sorted Arrays 题解
- LeetCode[Day 3] Longest Substring Without... 题解
- LeetCode [Day 4] Add Two Numbers 题解