|
| 1 | +package code; |
| 2 | +import java.util.Arrays; |
| 3 | +import java.util.HashMap; |
| 4 | + |
| 5 | +/* |
| 6 | + * 923. 3Sum With Multiplicity |
| 7 | + * 题意:3Sum有几种?数组中有重复数字 |
| 8 | + * 难度:Medium |
| 9 | + * 分类:Two Pointers |
| 10 | + * 思路:由于本题只要求给出多少种Int值,所以不一定非要用3Sum的思路,有很多更简答的方法 |
| 11 | + * 3种思路 |
| 12 | + * Tips: |
| 13 | + */ |
| 14 | +public class lc923 { |
| 15 | + public int threeSumMulti(int[] A, int target) { |
| 16 | + int res = 0; |
| 17 | + HashMap<Integer, Integer> hm = new HashMap(); |
| 18 | + for (int i = 0; i < A.length ; i++) { |
| 19 | + res = (res+hm.getOrDefault(target-A[i],0))%1000000007; // i之前的数字,两个组合起来,是否 == target-A[i] |
| 20 | + for (int j = 0; j < i ; j++) { |
| 21 | + hm.put(A[i]+A[j], hm.getOrDefault(A[i]+A[j], 0)+1); |
| 22 | + } |
| 23 | + } |
| 24 | + return res; |
| 25 | + } |
| 26 | + public int threeSumMulti2(int[] A, int target) { //3Sum的思路 |
| 27 | + int res = 0; |
| 28 | + Arrays.sort(A); |
| 29 | + for (int i = 0; i < A.length-2 ; i++) { |
| 30 | + int left = i+1, right = A.length-1; |
| 31 | + while(left<right){ |
| 32 | + if(A[i]+A[left]+A[right]<target) left++; |
| 33 | + else if(A[i]+A[left]+A[right]>target) right--; |
| 34 | + else if(A[left]==A[right]) { //如果相等,则直接 C N 取 2,计算出来,然后break |
| 35 | + res = (res + (right-left)*(right-left+1)/2)%1000000007; |
| 36 | + break; //不用继续移动指针了 |
| 37 | + } else { |
| 38 | + int leftcount = 1, rightcount = 1; |
| 39 | + while(A[left]==A[left+1]) { |
| 40 | + left++; |
| 41 | + leftcount++; |
| 42 | + } |
| 43 | + while(A[right]==A[right-1]) { |
| 44 | + right--; |
| 45 | + rightcount++; |
| 46 | + } |
| 47 | + res = (res + leftcount*rightcount)%1000000007; |
| 48 | + left++; //别忘了,最后还要操作一下 |
| 49 | + right--; |
| 50 | + } |
| 51 | + } |
| 52 | + } |
| 53 | + return res; |
| 54 | + } |
| 55 | + |
| 56 | + public int threeSumMulti3(int[] A, int target) { //直接数学计算 |
| 57 | + long[] c = new long[101]; |
| 58 | + for (int a : A) c[a]++; |
| 59 | + long res = 0; |
| 60 | + for (int i = 0; i <= 100; i++) // 题目给了值不超过100 |
| 61 | + for (int j = i; j <= 100; j++) { |
| 62 | + int k = target - i - j; |
| 63 | + if (k > 100 || k < 0) continue; |
| 64 | + if (i == j && j == k) |
| 65 | + res += c[i] * (c[i] - 1) * (c[i] - 2) / 6; |
| 66 | + else if (i == j && j != k) |
| 67 | + res += c[i] * (c[i] - 1) / 2 * c[k]; |
| 68 | + else if (j < k) |
| 69 | + res += c[i] * c[j] * c[k]; |
| 70 | + } |
| 71 | + return (int)(res % (1e9 + 7)); |
| 72 | + } |
| 73 | +} |
0 commit comments