Skip to content

Commit da22585

Browse files
committed
Rearrange String K Distance Apart
1 parent ec0e274 commit da22585

File tree

5 files changed

+226
-2
lines changed

5 files changed

+226
-2
lines changed

.vscode/markdown.code-snippets

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,17 @@
2626
"",
2727
"## Discussion",
2828
"",
29-
"### Time Complexity",
29+
"### Approach",
3030
"",
31-
"### Space Complexity",
31+
"#### Time Complexity",
32+
"",
33+
"#### Space Complexity",
34+
"",
35+
"### Alternate Approach 1",
36+
"",
37+
"#### Time Complexity - Alternate Approach 1",
38+
"",
39+
"#### Space Complexity - Alternate Approach 1",
3240
"",
3341
"## Notes",
3442
"",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package EducativeIo.Courses.GrokkingTheCodingInterview.Ch13_TopKElements.PC1_RearrangeStringKDistanceApart.Java;
2+
3+
import java.util.HashMap;
4+
import java.util.LinkedList;
5+
import java.util.Map;
6+
import java.util.PriorityQueue;
7+
import java.util.Queue;
8+
9+
public class Solution {
10+
public static void main(String[] args) {
11+
System.out.println("Reorganized string: " + reorganizeString("mmpp", 2));
12+
System.out.println("Reorganized string: " + reorganizeString("Programming", 3));
13+
System.out.println("Reorganized string: " + reorganizeString("aab", 2));
14+
System.out.println("Reorganized string: " + reorganizeString("aappa", 3));
15+
}
16+
17+
public static String reorganizeString(String str, int k) {
18+
if (k <= 1) {
19+
return str;
20+
}
21+
22+
Map<Character, Integer> charFrequencyMap = new HashMap<>();
23+
for (char chr : str.toCharArray())
24+
charFrequencyMap.put(chr, charFrequencyMap.getOrDefault(chr, 0) + 1);
25+
26+
PriorityQueue<Map.Entry<Character, Integer>> maxHeap =
27+
new PriorityQueue<Map.Entry<Character, Integer>>(
28+
(e1, e2) -> e2.getValue() - e1.getValue());
29+
30+
// add all characters to the max heap
31+
maxHeap.addAll(charFrequencyMap.entrySet());
32+
33+
Queue<Map.Entry<Character, Integer>> queue = new LinkedList<>();
34+
StringBuilder resultString = new StringBuilder(str.length());
35+
while (!maxHeap.isEmpty()) {
36+
Map.Entry<Character, Integer> currentEntry = maxHeap.poll();
37+
// append the current character to the result string and decrement its count
38+
resultString.append(currentEntry.getKey());
39+
currentEntry.setValue(currentEntry.getValue() - 1);
40+
queue.offer(currentEntry);
41+
if (queue.size() == k) {
42+
Map.Entry<Character, Integer> entry = queue.poll();
43+
if (entry.getValue() > 0)
44+
maxHeap.add(entry);
45+
}
46+
}
47+
48+
// if we were successful in appending all the characters to the result string, return it
49+
return resultString.length() == str.length() ? resultString.toString() : "";
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package EducativeIo.Courses.GrokkingTheCodingInterview.Ch13_TopKElements.PC1_RearrangeStringKDistanceApart.Java;
2+
3+
import static org.junit.jupiter.api.Assertions.*;
4+
5+
import java.time.Duration;
6+
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.api.AfterEach;
8+
import org.junit.jupiter.api.BeforeEach;
9+
10+
public class SolutionTest {
11+
12+
Solution solution;
13+
14+
@BeforeEach
15+
public void setUp() throws Exception {
16+
solution = new Solution();
17+
}
18+
19+
@AfterEach
20+
public void tearDown() throws Exception {
21+
solution = null;
22+
}
23+
24+
@Test
25+
public void MainFunction() {
26+
assertTimeout(Duration.ofMillis(500), () -> {
27+
String[] args = new String[0];
28+
assertAll(() -> Solution.main(args));
29+
});
30+
}
31+
32+
@Test
33+
public void TrivialCase1() {
34+
String str = "mmpp";
35+
int k = 2;
36+
assertTimeout(Duration.ofMillis(500), () -> {
37+
String expected = "pmpm";
38+
String actual = Solution.reorganizeString(str, k);
39+
assertEquals(expected, actual);
40+
});
41+
}
42+
43+
@Test
44+
public void TrivialCase2() {
45+
String str = "Programming";
46+
int k = 3;
47+
assertTimeout(Duration.ofMillis(500), () -> {
48+
String expected = "rgmPrgmiano";
49+
String actual = Solution.reorganizeString(str, k);
50+
assertEquals(expected, actual);
51+
});
52+
}
53+
54+
@Test
55+
public void TrivialCase3() {
56+
String str = "aab";
57+
int k = 2;
58+
assertTimeout(Duration.ofMillis(500), () -> {
59+
String expected = "aba";
60+
String actual = Solution.reorganizeString(str, k);
61+
assertEquals(expected, actual);
62+
});
63+
}
64+
65+
@Test
66+
public void TrivialCase4() {
67+
String str = "aappa";
68+
int k = 3;
69+
assertTimeout(Duration.ofMillis(500), () -> {
70+
String expected = "";
71+
String actual = Solution.reorganizeString(str, k);
72+
assertEquals(expected, actual);
73+
});
74+
}
75+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"type": "Coding",
3+
"name": "Rearrange String K Distance Apart",
4+
"origin": {
5+
"name": "Educative",
6+
"link": "https://www.educative.io/courses/grokking-the-coding-interview/m2E4y26k3LE"
7+
},
8+
"companies": ["", ""],
9+
"categories": [{
10+
"name": "Courses",
11+
"children": [{
12+
"name": "Grokking the Coding Interview: Patterns for Coding Questions",
13+
"children": []
14+
}]
15+
},
16+
{
17+
"name": "Difficulty",
18+
"children": [{
19+
"name": "Hard",
20+
"children": []
21+
}]
22+
},
23+
{
24+
"name": "Pattern",
25+
"children": [{
26+
"name": "Top K Elements",
27+
"children": []
28+
}]
29+
}
30+
],
31+
"tags": ["Top K Elements"],
32+
"buckets": []
33+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Problem Definition
2+
3+
## Description
4+
5+
Given a string and a number ‘K’, find if the string can be rearranged such that the same characters are at least ‘K’ distance apart from each other.
6+
7+
Example 1:
8+
9+
```plaintext
10+
Input: "mmpp", K=2
11+
Output: "mpmp" or "pmpm"
12+
Explanation: All same characters are 2 distance apart.
13+
```
14+
15+
Example 2:
16+
17+
```plaintext
18+
Input: "Programming", K=3
19+
Output: "rgmPrgmiano" or "gmringmrPoa"
20+
Explanation: All same characters are 3 distance apart.
21+
```
22+
23+
Example 3:
24+
25+
```plaintext
26+
Input: "aab", K=2
27+
Output: "aba"
28+
Explanation: All same characters are 2 distance apart.
29+
```
30+
31+
Example 4:
32+
33+
```plaintext
34+
Input: "aappa", K=3
35+
Output: ""
36+
Explanation: We cannot find an arrangement of the string where any two 'a' are 3 distance apart.
37+
```
38+
39+
## Discussion
40+
41+
### Approach
42+
43+
This problem follows the **Top ‘K’ Numbers** pattern and is quite similar to **Rearrange String**. The only difference is that in the ‘Rearrange String’ the same characters need not be adjacent i.e., they should be at least ‘2’ distance apart (in other words, there should be at least one character between two same characters), while in the current problem, the same characters should be ‘K’ distance apart.
44+
45+
Following a similar approach, since we were inserting a character back in the heap in the next iteration, in this problem, we will re-insert the character after ‘K’ iterations. We can keep track of previous characters in a queue to insert them back in the heap after ‘K’ iterations.
46+
47+
#### Time Complexity
48+
49+
The time complexity of the above algorithm is O(N*logN) where ‘N’ is the number of characters in the input string.
50+
51+
#### Space Complexity
52+
53+
The space complexity will be O(N), as in the worst case, we need to store all the ‘N’ characters in the HashMap.
54+
55+
## Notes
56+
57+
## References

0 commit comments

Comments
 (0)