leetCode 之 K Sum()問題

import java.util.*;
//Given nums = [2, 7, 11, 15], target = 9,
//Because nums[0] + nums[1] = 2 + 7 = 9,
//return [0, 1].
//思路:先建立一個int[2]數組result存放返回值,然後遍歷,
//其中一個爲cur=nums[i],另一個toFind=target-nums[i],//如果發現之前需要這個差值,那就找index。
//如果沒有,就put到map裏  //返回result,循環結束
public class Solution { public int[] twoSum(int[] nums, int target) { 
//創建一下數組,要存兩個index的數組。 
int[] result = new int[2]; //這裏用hashtable也行,看心情。 
Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 
//掃一遍數組,一邊掃一邊存
 for(int i = 0; i < nums.length; i++)
{ int cur = nums[i]; //這裏搞出來個差值,其實差值是在沒找到之後添加到map裏面的。 
int toFind = target - cur; 
//如果發現之前需要這個差值,那就找index。
 if(map.containsKey(cur)){ result[0] = map.get(cur); result[1] = i; return result; } 
//如果沒有,就put到map裏面 
else{ map.put(toFind, i); 
} } 
return result;
 }}
如果遇到threeSum呢?fourSum?

【題目】

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

提示:

  • a<=b<=c
  • 避免結果集中有重複,因爲數組時排好序的,所以當一個數被放到結果集中的時候,其後面和它相等的直接被跳過。

    For example, given array S = {-1 0 1 2 -1 -4},

    A solution set is:
    (-1, 0, 1)
    (-1, -1, 2)
【思路】

K Sum問題是一個系列,博客 http://tech-wonderland.net/blog/summary-of-ksum-problems.html 和https://blog.csdn.net/ljiabin/article/details/40620579總結得比較完整,有興趣可以去看。

暴力解決法:三層for循環,但是時間複雜度是O(n^3),而且還要處理重複的問題,顯然不是題目想要的解法。

排序算法:時間複雜度爲O(nlgn),小於O(n^2),那麼我們不妨先對數組排個序。

對於3Sum ,我們可以先固定一個數,然後找另外兩個數之和爲第一個數的相反數就可以了。

【Java代碼】O(n^2)

[java] view plain copy
  1. public class Solution {  
  2.     List<List<Integer>> ret = new ArrayList<List<Integer>>();  
  3.       
  4.     public List<List<Integer>> threeSum(int[] num) {  
  5.         if (num == null || num.length < 3return ret;  //如果數組元素個數<3
  6.           
  7.         Arrays.sort(num);  //調用Arrays的sort方法對num從小到大排序;
  8.           
  9.         int len = num.length;  //用for循環遍歷,若兩個元素相等,則跳出,調用find(),尋找兩個數與num[i]的和爲0;
  10.         for (int i = 0; i < len-2; i++) {  
  11.             if (i > 0 && num[i] == num[i-1]) continue;  
  12.             find(num, i+1, len-1, num[i]); //尋找兩個數與num[i]的和爲0  
  13.         }  
  14.           
  15.         return ret;  
  16.     }  
  17.       //find方法,num[l] + num[r] + target == 0,則這三個值add到列表對象中
  18.     public void find(int[] num, int begin, int end, int target) {  
  19.         int l = begin, r = end;  
  20.         while (l < r) {  
  21.             if (num[l] + num[r] + target == 0) {  
  22.                 List<Integer> ans = new ArrayList<Integer>();  
  23.                 ans.add(target);  
  24.                 ans.add(num[l]);  
  25.                 ans.add(num[r]);  
  26.                 ret.add(ans); //放入結果集中  
  27.                 while (l < r && num[l] == num[l+1]) l++;  
  28.                 while (l < r && num[r] == num[r-1]) r--;  
  29.                 l++;  
  30.                 r--;  
  31.             } else if (num[l] + num[r] + target < 0) {  
  32.                 l++;  
  33.             } else {  
  34.                 r--;  
  35.             }  
  36.         }  
  37.     }  
  38. }  

注意,對於 num[i],尋找另外兩個數時,只要從 i+1 開始找就可以了。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章