题1、给定一个int数组,一个数sum,求数组中和为sum的任意2个数的组合
1 @Test 2 public void test_find2() { 3 int[] arr = { -1, 0, 2, 3, 4, 7, 8, 9, 10 }; 4 int sum = 9; 5 Arrays.sort(arr); 6 List<TwoTuple<Integer, Integer>> result = new ArrayList<>(); 7 8 int i = 0; 9 int j = arr.length - 1; 10 while (i < j) { 11 if (arr[i] + arr[j] == sum) { 12 result.add(new TwoTuple<Integer, Integer>(arr[i], arr[j])); 13 i++; 14 j--; 15 } else if (arr[i] + arr[j] < sum) { 16 i++; 17 } else { // > sum 18 j--; 19 } 20 } 21 System.out.println(result); 22 } // out: [-1:10, 0:9, 2:7]
题2、给定一个int数组,一个数sum,求数组中和为sum的任意3个数的组合
1 @Test 2 public void test_find3() { 3 int[] arr = { -1, 0, 2, 3, 4, 7, 8, 9, 10 }; 4 int sum = 9; 5 Arrays.sort(arr); 6 Set<ThreeTuple<Integer, Integer, Integer>> result = new LinkedHashSet<>(); 7 8 for (int i = 0; i < arr.length; i++) { 9 int temp = arr[i]; 10 swap(arr, i, 0); 11 int start = 1; 12 int end = arr.length - 1; 13 while (start < end) { 14 if (arr[start] + arr[end] == sum - temp) { 15 int[] threeNum = {temp, arr[start], arr[end]}; 16 Arrays.sort(threeNum); 17 result.add(new ThreeTuple<>(threeNum[0], threeNum[1], threeNum[2])); 18 start++; 19 end--; 20 } else if (arr[start] + arr[end] > sum - temp) { 21 end--; 22 } else { 23 start++; 24 } 25 } 26 swap(arr, i, 0); // 还原 27 } 28 System.out.println(result); 29 } // out: [-1:0:10, -1:2:8, -1:3:7, 0:2:7, 2:3:4] 30 31 private void swap(int[] a, int i, int j) { 32 int temp = a[i]; 33 a[i] = a[j]; 34 a[j] = temp; 35 }
上面两题用到的元组类:
1 class TwoTuple<A, B> { 2 public final A first; 3 public final B second; 4 5 public TwoTuple(A a, B b) { 6 this.first = a; 7 this.second = b; 8 } 9 10 @Override public String toString() { 11 return first + ":" + second; 12 } 13 14 @Override 15 public int hashCode() { 16 final int prime = 31; 17 int result = 1; 18 result = prime * result + ((first == null) ? 0 : first.hashCode()); 19 result = prime * result + ((second == null) ? 0 : second.hashCode()); 20 return result; 21 } 22 23 @Override 24 public boolean equals(Object obj) { 25 if (this == obj) 26 return true; 27 if (obj == null) 28 return false; 29 if (getClass() != obj.getClass()) 30 return false; 31 TwoTuple<?, ?> other = (TwoTuple<?, ?>) obj; 32 if (first == null) { 33 if (other.first != null) 34 return false; 35 } else if (!first.equals(other.first)) 36 return false; 37 if (second == null) { 38 if (other.second != null) 39 return false; 40 } else if (!second.equals(other.second)) 41 return false; 42 return true; 43 } 44 }
1 class ThreeTuple<A, B, C> extends TwoTuple<A, B> { 2 public final C third; 3 4 public ThreeTuple(A a, B b, C c) { 5 super(a, b); 6 this.third = c; 7 } 8 9 @Override public String toString() { 10 return super.toString() + ":" + third; 11 } 12 13 @Override 14 public int hashCode() { 15 final int prime = 31; 16 int result = super.hashCode(); 17 result = prime * result + ((third == null) ? 0 : third.hashCode()); 18 return result; 19 } 20 21 @Override 22 public boolean equals(Object obj) { 23 if (this == obj) 24 return true; 25 if (!super.equals(obj)) 26 return false; 27 if (getClass() != obj.getClass()) 28 return false; 29 ThreeTuple<?, ?, ?> other = (ThreeTuple<?, ?, ?>) obj; 30 if (third == null) { 31 if (other.third != null) 32 return false; 33 } else if (!third.equals(other.third)) 34 return false; 35 return true; 36 } 37 }
题3、给定一个int正整数数组,一个数sum,求数组中和为sum的k个数的组合有多少种(k任意)。
另开一博客讨论这个问题。
指路:【算法习题】正整数数组中和为sum的任意个数的组合数——待完成