1. 程式人生 > >Coursera Algorithms week1 Interview Questions: 3Sum in quadratic time

Coursera Algorithms week1 Interview Questions: 3Sum in quadratic time

import 排好序 .get 部分 ase prop 計算 pan 出了

題目要求:

Design an algorithm for the 3-SUM problem that takes time proportional to n2 in the worst case. You may assume that you can sort the n integers in time proportional to n2 or better.

分析:

《算法4》這本書提供的TwoSumFast解法為NlogN,ThreeSumFast解法為N2logN,根據課後練習,要實現3Sum復雜度為N2,建議先把2Sum復雜度實現為N。同時教材提示用排好序的數組可以實現復雜度N。我想了很久,沒有發現排好序的數組對復雜度降至N有太大幫助,於是在網上搜索了下大家的做法。網上的大部分都是建議用set或map來做,我決定采用map試試,果然用map很方便。代碼如下:

 1 import java.util.Arrays;
 2 import java.util.HashMap;
 3 
 4 public class TwoSumLinear {
 5     public static int count(int[] a){
 6         int cnt = 0;
 7         int n = a.length;
 8         HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
 9         for(int i =0; i<n;i++){
10 if(map.get(a[i]) == null) map.put(a[i], i); 11 Integer negIndex = map.get(-a[i]); 12 if(negIndex != null && negIndex != i){ 13 System.out.println("a["+negIndex+"]="+(-a[i])+"和a["+i+"]="+a[i]); 14 cnt++; 15 } 16
} 17 return cnt; 18 } 19 public static void main(String[] args){ 20 int[] a = { 30, -40, -20, -10, 40, 0, 10, 5 }; 21 System.out.println(Arrays.toString(a)); 22 System.out.println(count(a)); 23 } 24 }

3Sum的作業提示可以先將數組排序,基於這個思路,結合寫過的2Sum線性實現方法,寫出了復雜度為N2的3Sum,個人認為實現的方式已經很精簡了。

 1 import java.util.Arrays;
 2 import java.util.HashMap;
 3 
 4 public class ThreeSumQuadratic {
 5     public static int count(int[] a, int target) {
 6         Arrays.sort(a);// 數組從小到大排序,後面要使用有序數組的性質簡化運算
 7         System.out.println(Arrays.toString(a));
 8         System.out.println("target="+target);
 9         int cnt = 0;
10         int n = a.length;
11         HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
12         for (int i = 0; i < n; i++) {
13             map.put(a[i], i); //以數組value為key,index為map值
14         }
15         for (int i = 0; i < n - 1; i++) {//i不會超過n-2
16             for (int j = i + 1; j < n; j++) {//j從i+1開始統計,不會超過n-1
17                 int smallValue = a[i] + a[j]; //因為排好序了,所以最開始的a[i]+a[j]
18                 if (smallValue > target) //當a[i]+a[j]>target時沒必要計算了,因為後續的查找就會重復
19                     break;
20                 int bigValue = target-smallValue; //計算出對應的數值較大的value
21                 Integer bigIndex = map.get(bigValue); //查找數值較大的value所在的位置
22                 if (bigIndex != null && bigIndex > i && bigIndex > j) {
23                     System.out.println(
24                             "[" + i + "]=" + a[i] + ",[" + j + "]" + a[j] + ",[" + bigIndex + "]" + (bigValue));
25                     cnt++;
26                 }
27             }
28         }
29         return cnt;
30     }
31 
32     public static void main(String[] args) {
33         int[] a = { 30, -40, -20, -10, 40, 0, 10, 5 };        
34         System.out.println(count(a,0));
35     }
36 }

Coursera Algorithms week1 Interview Questions: 3Sum in quadratic time