Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 84fa776

Browse files
923. 3Sum With Multiplicity (Sorting & Two Pointers)
1 parent 29ac15a commit 84fa776

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.cheehwatang.leetcode;
2+
3+
import java.util.Arrays;
4+
5+
// Time Complexity : O(n^2),
6+
// where 'n' is the length of 'arr'.
7+
// We traverse 'arr'. With each 'arr[i]', we use two pointers to traverse to find the triplets.
8+
// Arrays.sort() function has a time complexity of O(n logn).
9+
//
10+
// Space Complexity : O(1),
11+
// as the auxiliary space used is independent of the input 'arr'.
12+
13+
public class ThreeSumWithMultiplicity_Sorting_TwoPointers {
14+
15+
// Approach:
16+
// Using sorting and two pointers to traverse the sorted array and check each number if they sum to 'target'.
17+
// Note that, i < j < k and arr[i] + arr[j] + arr[k] == target,
18+
// do not require the index as the sum is not dependent on the index, so sorting is fine.
19+
20+
public int threeSumMulti(int[] arr, int target) {
21+
int n = arr.length;
22+
Arrays.sort(arr);
23+
long count = 0;
24+
25+
// With each 'i', use two pointers 'j' and 'k' to traverse the remaining numbers to the right of 'i'.
26+
for (int i = 0; i < n - 2; i++) {
27+
// If the smallest number is greater than 'target',
28+
// then the remaining numbers (which are greater) are impossible to sum to be equal to 'target'.
29+
if (arr[i] + arr[i + 1] + arr[i + 2] > target) break;
30+
// If the largest number is less than 'target', meaning we need to increase 'i' to get a larger number.
31+
if (arr[i] + arr[n - 1] + arr[n - 2] < target) continue;
32+
33+
// After the check, traverse with 'j' and 'k' from both ends.
34+
int j = i + 1;
35+
int k = n - 1;
36+
while (j < k) {
37+
int sum = arr[i] + arr[j] + arr[k];
38+
// Move 'j' to right if sum is less than target.
39+
if (sum < target) j++;
40+
// Move 'k' to left if sum is greater than target.
41+
else if (sum > target) k--;
42+
// If it is equal, keep track of the frequency for both 'arr[j]' and 'arr[k]'.
43+
else {
44+
int countJ = 1;
45+
while (j < k && arr[j] == arr[j + 1]) {
46+
j++;
47+
countJ++;
48+
}
49+
int countK = 1;
50+
while (j < k && arr[k] == arr[k - 1]) {
51+
k--;
52+
countK++;
53+
}
54+
// If both are same, get the geometric sum for 'countJ' + 'countK' - 1.
55+
// Example: [1,2,2,2,2], target = 5. With arr[i] = 1, arr[j] == arr[k] = 2.
56+
// Note that the "j < k" will break with 'j' overlapping with 'k'.
57+
// Thus, 'countJ' = 4 and 'countK' = 1.
58+
// 'countJ' + 'countK' - 1 = 4, which results in 4 * 3 / 2 = 6 possible combinations.
59+
if (arr[j] == arr[k]) {
60+
int frequency = countJ + countK - 1;
61+
count += (long) frequency * (frequency - 1) / 2;
62+
}
63+
// If they are different, the count increase by the multiplication for both.
64+
// Example: [1,2,2,3,3], target = 6. With arr[i] = 1, arr[j] = 2 and arr[k] = 3.
65+
// There are 2 * 2 = 4 possible combinations for the 2 and 3.
66+
else
67+
count += (long) countJ * countK;
68+
// Once done, move both pointers to continue check the other numbers.
69+
j++;
70+
k--;
71+
}
72+
}
73+
}
74+
return (int) (count % (1e9 + 7));
75+
}
76+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /