【Leetcode】767. Reorganize String
題目地址:
https://leetcode.com/problems/reorganize-string/
給定一個長為 l l l的字串 s s s,只含小寫英文字母。將其字母重排,使得相鄰的字母不同,返回重排後的字串。如果不存在這樣的合法重排,則返回空串。
直覺上來講,只需要將出現最多次數的字元隔一個位置放,然後將別的字母插在中間即可。我們證明一個結論:存在那樣的合法重排當且僅當出現最多的字母出現次數小於等於 l / 2 l/2 l/2(當 l l l是偶數)或者小於等於 l / 2 + 1 l/2+1 l/2+1(當 l l l是奇數)。
證明:必要性顯然,鴿籠原理即可。充分性,只需證明確實存在一個方法即可。演算法如下:開一個字元陣列 c c c,先找到出現最多次數的字母,將其填到 c [ 0 ] , c [ 2 ] , c [ 4 ] , . . . , c [ 2 i ] c[0],c[2],c[4],...,c[2i] c[0],c[2],c[4],...,c[2i],然後找到出現次數第二多的字母,填到 c [ 2 i + 2 ] , c [ 2 i + 4 ] , . . . c[2i+2],c[2i+4],... c[2i+2],c[2i+4],...,如果填不下了,就從 c [ 1 ] , c [ 3 ] , c [ 5 ] , . . . c[1],c[3],c[5],... c[1],c[3],c[5],...這樣開始填。由於有上面所說的個數限制,導致不可能有相鄰的字母相同的情況發生。
程式碼實現方面,可以直接先填,然後驗證。挑出現最多的字母可以用最大堆來做。程式碼如下:
import java.util.PriorityQueue;
public class Solution {
public String reorganizeString(String S) {
char[] str = new char[S.length()];
int[] count = new int[26];
for (int i = 0; i < S.length(); i++) {
count[S.charAt(i) - 'a']++;
}
PriorityQueue<Character> maxHeap = new PriorityQueue<>((c1, c2) -> -Integer.compare(count[c1 - 'a'], count[c2 - 'a']));
for (char ch = 'a'; ch <= 'z'; ch++) {
maxHeap.offer(ch);
}
int idx = 0;
while (!maxHeap.isEmpty()) {
char max = maxHeap.poll();
while (count[max - 'a'] > 0) {
str[idx] = max;
count[max - 'a']--;
idx += 2;
// 出界了,從str[1]開始填
if (idx >= str.length) {
idx = 1;
}
}
}
// 如果有相鄰字母相同了,說明不存在合法解,返回空串
for (int i = 1; i < str.length; i++) {
if (str[i] == str[i - 1]) {
return "";
}
}
return new String(str);
}
}
時空複雜度 O ( l ) O(l) O(l)。
相關文章
- [LeetCode] Rotate StringLeetCode
- [leetcode] Scramble StringLeetCode
- Leetcode 481 Magical StringLeetCode
- Leetcode Reverse Words in a StringLeetCode
- leetcode Reverse Words in a StringLeetCode
- leetcode String to Integer (atoi)LeetCode
- Leetcode-Scramble StringLeetCode
- Leetcode - String to Integer (atoi)LeetCode
- Scramble String leetcode javaLeetCodeJava
- leetcode 344. Reverse StringLeetCode
- Leetcode 8 String to Integer (atoi)LeetCode
- LeetCode-Reverse Vowels of a StringLeetCode
- LeetCode-Decode StringLeetCode
- LeetCode-Reverse Words in a StringLeetCode
- Leetcode-Interleaving StringLeetCode
- String to Integer (atoi) leetcode javaLeetCodeJava
- Interleaving String leetcode javaLeetCodeJava
- Reverse Words in a String leetcode javaLeetCodeJava
- Leetcode 151 Reverse Words in a StringLeetCode
- 【Leetcode】1528. Shuffle StringLeetCode
- LeetCode-Reverse Words in a String IILeetCode
- [LeetCode] 678. Valid Parenthesis StringLeetCode
- [LeetCode] 844. Backspace String CompareLeetCode
- LeetCode 438. Find All Anagrams in a StringLeetCode
- 344. Reverse String--LeetCode RecordLeetCode
- LeetCode151:Reverse Words in a StringLeetCode
- LeetCode C++ 387. First Unique Character in a String【String/Hash Table】簡單LeetCodeC++
- LeetCode-Rearrange String k Distance ApartLeetCode
- leetcode第一刷_Interleaving StringLeetCode
- LeetCode 394. Decode String All In OneLeetCode
- LeetCode String to Integer (atoi)(008)解法總結LeetCode
- [LeetCode] String to Integer (atoi) 字串轉為整數LeetCode字串
- 【LeetCode 8_字串_實現】String to Integer (atoi)LeetCode字串
- [LeetCode] 3163. String Compression IIILeetCode
- To Rebuild / Reorganize Sys.Con$ To Reduce Its Size-783722.1Rebuild
- Leetcode 8. String to Integer (atoi) 字串轉整數 (atoi)LeetCode字串
- LeetCode之Construct String from Binary Tree(Kotlin)LeetCodeStructKotlin
- [LeetCode-Easy]344. Reverse String-逆置字串LeetCode字串