Sum 类型题目总结

Sum类的题目一般这样:

input: nums[], target

output: satisfied arrays/ lists/ number

拿到题目,首先分析:

1. 是几个数的sum

2. sum是要求等于target还是小于还是大于还是closest

3. 返回的是原数组下标还是其他

 

对于这类题目,我们经常用双指针的方法。即排序后,左指针指向起点,右指针指向终点。

  • 如果sum等于target,加入结果/总数目+1
  • 如果sum大于target,右指针左移
  • 如果sum小于target,左指针右移

还有些情况下,我们需考虑去重。去重有两种方法:

  • 利用HashSet预先存下满足条件的值
  • 指针移动去重

第一种方法由于常常需要更多的空间,所以不太建议。

第二种方法的模板是:先判断值,再去重。(去重是当前的element和它前一个element比较)

这里给出一个 n Sum 的模板

 1 public class Solution {
 2     public void nSum(int[] nums, int target) {
 3         // Check whether input is valid
 4         if (nums == null || nums.length < n) {
 5             return;
 6         }
 7 
 8         // Sort input array
 9         Arrays.sort(nums);
10 
11         // Fix one parameter
12         int length = nums.length;
13         for (int i = 0; i < length - n + 1; i++) {
14             // Avoid duplicate 1
15             if (i > 0 && nums[i] == nums[i - 1]) {
16                 continue;
17             }
18 
19             // Fix more parameters
20             ...
21             // Until two parameters left
22 
23             // start and end are decided by innerest parameter value
24             int left = start;
25             int right = end;
26             while (left < right) {
27                 int sum = nums[i] + .. + nums[left] + nums[right];
28                 if (sum == target) {
29                     // Some action
30                     left++;
31                     right--;
32                     // Avoid duplicate 2
33                     while (left < right && nums[left] == nums[left - 1]) {
34                         left++;
35                     }
36                     while (left < right && nums[right] == nums[right + 1]) {
37                         right--;
38                     }
39                 } else if (sum < target) {
40                     left++;
41                     while (left < right && nums[left] == nums[left - 1]) {
42                         left++;
43                     }
44                 } else {
45                     right--;
46                     while (left < right && nums[right] == nums[right + 1]) {
47                         right--;
48                     }
49                 }
50             }
51         }
52     }
53 }

Example:

Two Sum II

3Sum

 

以下是模板的变型问题:

1. 要返回原数组的下标。

这种情况下就不太好排序,因为排序会改变数组下标。

一般用HashMap做。

Example:

2Sum

2. 返回所有满足小于target的组合的数目

Example:

3Sum Smaller

3. 要求是closest

Example:

3Sum Closest

4. 利用HashMap化为2Sum问题

Example:

4Sum

posted @ 2015-11-05 02:26  树獭君  阅读(422)  评论(0编辑  收藏  举报