|
38 | 38 | public class ReorganizeString { |
39 | 39 |
|
40 | 40 | // V0 |
| 41 | + // IDEA : HASHMAP + HEAP |
| 42 | + // https://github.com/yennanliu/CS_basics/blob/master/leetcode_python/Greedy/reorganize-string.py#L35 |
| 43 | + public String reorganizeString(String S) { |
| 44 | + // Step 1: Count the frequency of each character |
| 45 | + Map<Character, Integer> charCountMap = new HashMap<>(); |
| 46 | + for (char c : S.toCharArray()) { |
| 47 | + charCountMap.put(c, charCountMap.getOrDefault(c, 0) + 1); |
| 48 | + } |
| 49 | + |
| 50 | + // Step 2: Use a priority queue (max heap) to keep characters sorted by |
| 51 | + // frequency |
| 52 | + /** NOTE !!! |
| 53 | + * |
| 54 | + * we use PQ to track the characters count sorted in order |
| 55 | + */ |
| 56 | + PriorityQueue<Map.Entry<Character, Integer>> maxHeap = new PriorityQueue<>( |
| 57 | + (a, b) -> b.getValue() - a.getValue()); |
| 58 | + maxHeap.addAll(charCountMap.entrySet()); |
| 59 | + |
| 60 | + // Step 3: Initialize a StringBuilder with a placeholder to avoid indexing |
| 61 | + // errors |
| 62 | + StringBuilder result = new StringBuilder("#"); |
| 63 | + |
| 64 | + // Step 4: While the heap is not empty, try to append characters |
| 65 | + while (!maxHeap.isEmpty()) { |
| 66 | + boolean stop = true; |
| 67 | + |
| 68 | + // Iterate over the heap to find the most common character that isn't the last |
| 69 | + // character in the result |
| 70 | + List<Map.Entry<Character, Integer>> tempList = new ArrayList<>(); |
| 71 | + while (!maxHeap.isEmpty()) { |
| 72 | + Map.Entry<Character, Integer> entry = maxHeap.poll(); |
| 73 | + char currentChar = entry.getKey(); |
| 74 | + int count = entry.getValue(); |
| 75 | + |
| 76 | + // If the current character is not the same as the last character in the result |
| 77 | + /** |
| 78 | + * NOTE !!! |
| 79 | + * |
| 80 | + * we get last element of stringBuilder via |
| 81 | + * |
| 82 | + * sb.charAt(sb.length() - 1) |
| 83 | + */ |
| 84 | + if (currentChar != result.charAt(result.length() - 1)) { |
| 85 | + stop = false; |
| 86 | + result.append(currentChar); |
| 87 | + |
| 88 | + // Decrease the count and add it back to the heap if it's still > 0 |
| 89 | + if (count - 1 > 0) { |
| 90 | + entry.setValue(count - 1); |
| 91 | + tempList.add(entry); |
| 92 | + } |
| 93 | + break; |
| 94 | + } else { |
| 95 | + tempList.add(entry); |
| 96 | + } |
| 97 | + } |
| 98 | + |
| 99 | + // Add back all remaining entries to the heap |
| 100 | + maxHeap.addAll(tempList); |
| 101 | + |
| 102 | + // If no valid character was found, break the loop |
| 103 | + if (stop) { |
| 104 | + break; |
| 105 | + } |
| 106 | + } |
| 107 | + |
| 108 | + // Step 5: Return the result or an empty string if reorganization is not |
| 109 | + // possible |
| 110 | + String reorganizedString = result.substring(1); // Remove the placeholder |
| 111 | + return reorganizedString.length() == S.length() ? reorganizedString : ""; |
| 112 | + } |
| 113 | + |
| 114 | + // V0' |
41 | 115 | // IDEA : HASHMAP |
42 | 116 | // TODO : fix below |
43 | 117 | // public String reorganizeString(String s) { |
|
0 commit comments