Skip to content

Commit cc08655

Browse files
committed
Refactor - Implement Sliding Window
A new approach - Sliding Window technique was applied to find more optimum solution but unfortunately both failed when the data is of large volume.
1 parent 753b602 commit cc08655

File tree

3 files changed

+160
-16
lines changed

3 files changed

+160
-16
lines changed

src/leetcode/datastructure/containsduplicate/two/README.MD

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ So we cannot sort as index needs to be preserved.
3434
### Pseudocode
3535

3636
for (i=0; i < nums.len; i++) // loop all nums
37-
for (j=i+1; j < nums.len; j++) // loop all numbs except i
37+
for (j=i+1; j < nums.len; j++) // loop all nums except i
3838

3939
if nums[i]=nums[j] and abs(i-j)<=k, return true
4040

@@ -52,7 +52,7 @@ Stores whole numbers from -2,147,483,648 to 2,147,483,647.
5252
```
5353

5454
### Understanding Case 1
55-
Initial logic below was failing case 1
55+
Initial logic below was failing test case 1
5656
```
5757
for (int i = 0; i < nums.length - 1; i++) {
5858
for ( int j = i+1; j < nums.length-1; j++ ) {
@@ -76,9 +76,9 @@ for ( int j = i+1; j < nums.length; j++ )
7676

7777
## Failed To Run
7878
The given test case failed to run with exception:
79-
Time Limit Exceeded
79+
**Time Limit Exceeded**
8080

81-
Data stored in failed-testcase.txt
81+
Data stored in testcase-48.txt
8282

8383
The first O(n^2) solution does not work for
8484
large input size.
@@ -121,9 +121,40 @@ If current == next,
121121
Find the index of next.
122122
Check condition.
123123

124-
Let's say we have 3 same numbers at different indexes. When we sort the array, 3 of them will appear one after another. And the value of k might be just less than the first index and the last. So we might have to check the current and the last.
124+
Let's say we have 3 same numbers at different indexes.
125+
When we sort the array, 3 of them will appear one after
126+
another. And the value of k might be just less than the
127+
first index and the last. So we might have to check the
128+
current and the last.
125129

126130
## Solution Accepted
127-
Runtime: 30 ms, faster than 37.52% of Java online submissions for Contains Duplicate II.
128-
Memory Usage: 49.3 MB, less than 54.65% of Java online submissions for Contains Duplicate II.
131+
Runtime: 30 ms, faster than 37.52% of Java online
132+
submissions for Contains Duplicate II.
133+
134+
Memory Usage: 49.3 MB, less than 54.65% of Java
135+
online submissions for Contains Duplicate II.
136+
137+
## Refactor
138+
The current solution is not efficient - time
139+
and space constraints are high.
140+
141+
Another solution would be using `Sliding Window`
142+
technique.
143+
144+
The constraint k defines the difference and
145+
this also means the distance between the two
146+
equal numbers.
147+
148+
### Pseudocode
149+
Iterate through array
150+
Create a new array of size of the window.
151+
Sort it.
152+
Check if two numbers are equal.
153+
154+
Two implementations are applied based on the technique.
155+
And both of them fails when large volume of data is
156+
processed.
157+
158+
159+
129160

src/leetcode/datastructure/containsduplicate/two/Solution.java

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,76 @@
1-
package leetcode.datastructure.duplicate.two;
1+
package leetcode.datastructure.containsduplicate.two;
22

33
import java.util.ArrayList;
44
import java.util.Arrays;
55
import java.util.stream.IntStream;
66
import static java.lang.Math.abs;
77

88
class Solution {
9-
public boolean containsNearbyDuplicate(int[] nums, int k) {
9+
10+
// Fails with Time Limit Exceeded for test case 47
11+
public boolean containsNearbyDuplicateSlidingWindowFAILS(int[] nums, int k) {
12+
if ( nums.length == 1 )
13+
return false;
14+
15+
if ( nums.length <= k && nums[0] == nums[nums.length-1]) {
16+
return true;
17+
}
18+
19+
int initialRange = nums.length-k == 1 ? k+1 : k;
20+
21+
if ( k == 1 || k == 2 || k % 2 > 0 ) initialRange = k+1;
22+
23+
int loops = nums.length-k;
24+
25+
int count = 0;
26+
for (; count < loops; count++) {
27+
int[] window = Arrays.copyOfRange(nums, count, initialRange + count);
28+
Arrays.sort(window);
29+
30+
for (int i = 0; i < window.length-1; i++) {
31+
if (window[i] == window[i+1])
32+
return true;
33+
}
34+
}
35+
36+
// Last few values would not have been compared
37+
// beacuase of the size of sliding window above.
38+
for (; count < nums.length-1 && k > 2; count++, k--) {
39+
for (int l = count; l < nums.length-1; l++) {
40+
41+
if (nums[count] == nums[l + 1])
42+
return true;
43+
}
44+
}
45+
46+
return false;
47+
}
48+
49+
// Fails with Time Limit Exceeded for test case 47
50+
public boolean containsNearbyDuplicateFails(int[] nums, int k) {
51+
int i = 0;
52+
int window = nums.length - k == 1 ? 2 : nums.length - k;
53+
54+
for (; i < window; i++) {
55+
for (int j = i; j < i + k; j++) {
56+
57+
if (nums[i] == nums[j+1])
58+
return true;
59+
}
60+
}
61+
62+
for (; i < nums.length-1 && window > 2; i++, k--) {
63+
for (int l = i; l < nums.length-1; l++) {
64+
65+
if (nums[i] == nums[l + 1])
66+
return true;
67+
}
68+
}
69+
70+
return false;
71+
}
72+
73+
public boolean containsNearbyDuplicateSUCCESS(int[] nums, int k) {
1074
int[] numsClone = nums.clone();
1175
Arrays.sort(numsClone);
1276
int duplicateCount = 0;
@@ -39,7 +103,7 @@ public boolean isLessThanK(int num, int duplicateCount, int k, int[] nums){
39103
ArrayList<Integer> indexes = new ArrayList<Integer>();
40104
int index = 0;
41105

42-
for (int j=0; j <= duplicateCount ;j++) {
106+
for (int j = 0; j <= duplicateCount; j++) {
43107

44108
index = IntStream.range(index, nums.length).
45109
filter(a -> num == nums[a]).

src/leetcode/datastructure/containsduplicate/two/SolutionTest.java

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
package leetcode.datastructure.duplicate.two;
1+
package leetcode.datastructure.containsduplicate.two;
22

33
import org.junit.jupiter.api.Assertions;
44
import org.junit.jupiter.api.Test;
55

6-
import java.util.Arrays;
7-
import java.util.List;
8-
import java.util.stream.Collectors;
9-
import java.util.stream.IntStream;
10-
116

127
class SolutionTest {
138
@Test
@@ -33,4 +28,58 @@ void shouldAssertTrueWithTestCase48() {
3328
Solution solution = new Solution();
3429
Assertions.assertTrue(solution.containsNearbyDuplicate(new int[]{313,64,612,515,412,661,244,164,492,744,233,579,62,786,342,817,838,396,230,79,570,702,124,727,586,542,919,372,187,626,869,923,103,932,368,891,411,125,724,287,575,326,88,125,746,117,363,8,881,441,542,653,211,180,620,175,747,276,832,772,165,733,574,186,778,586,601,165,422,956,357,134,857,114,450,64,494,679,495,205,859,136,477,879,940,139,903,689,954,335,859,78,20}, 22));
3530
}
31+
32+
@Test
33+
void shouldAssertTrueWithTestCase21() {
34+
Solution solution = new Solution();
35+
Assertions.assertTrue(solution.containsNearbyDuplicate(new int[]{1,2,1}, 2));
36+
}
37+
38+
@Test
39+
void shouldAssertFalseWithTestCase22() {
40+
Solution solution = new Solution();
41+
Assertions.assertFalse(solution.containsNearbyDuplicate(new int[]{13,23,1,2,3}, 5));
42+
}
43+
44+
@Test
45+
void shouldAssertFalseWithTestCase28() {
46+
Solution solution = new Solution();
47+
Assertions.assertFalse(solution.containsNearbyDuplicate(new int[]{0,1,2,3,4,5,0}, 5));
48+
}
49+
50+
@Test
51+
void shouldAssertFalseWithTestCase47() {
52+
Solution solution = new Solution();
53+
Assertions.assertTrue(solution.containsNearbyDuplicate(new int[]{99,99}, 2));
54+
}
55+
56+
@Test
57+
void shouldAssertFalseWithTestCase48() {
58+
Solution solution = new Solution();
59+
Assertions.assertFalse(solution.containsNearbyDuplicate(new int[]{1}, 1));
60+
}
61+
62+
@Test
63+
void shouldAssertTrueWithTestCase49() {
64+
Solution solution = new Solution();
65+
Assertions.assertTrue(solution.containsNearbyDuplicate(new int[]{1,2,3,4,5,6,7,8,9,9}, 3));
66+
}
67+
68+
@Test
69+
void shouldAssertTrueWithTestCase50() {
70+
Solution solution = new Solution();
71+
Assertions.assertTrue(solution.containsNearbyDuplicate(new int[]{1,2,2,3}, 3));
72+
}
73+
74+
@Test
75+
void shouldAssertTrueWithTestCase18() {
76+
Solution solution = new Solution();
77+
Assertions.assertTrue(solution.containsNearbyDuplicate(new int[]{2,2}, 3));
78+
}
79+
80+
@Test
81+
void shouldAssertTrueWithTestCase19() {
82+
Solution solution = new Solution();
83+
Assertions.assertTrue(solution.containsNearbyDuplicate(new int[]{0,1,2,3,4,5,0}, 6));
84+
}
3685
}

0 commit comments

Comments
 (0)