【刷題日記】leetcode-767 重構字串
一、題目
給定一個字串S,檢查是否能重新排布其中的字母,使得兩相鄰的字元不同。
若可行,輸出任意可行的結果。若不可行,返回空字串。
示例 1:
輸入: S = “aab”
輸出: “aba”
示例 2:
輸入: S = “aaab”
輸出: “”
注意:
S 只包含小寫字母並且長度在[1, 500]區間內。
二、解題
思路:
- “兩相鄰的字元不同” 推出重複次數最多的字元不能超過n/2 + 1 個,否則不能構成符合條件的字串
- 生成雜湊表,記錄每個字元出現的個數,將最大字元(X)從雜湊表剔除
- 如果滿足條件,遍歷雜湊表,將X放在遍歷開頭加入,直到除X外的所有字元都追加完成
- 此時若還有X沒有追加到重構的字串裡,從重構的字串尾部判斷是否能追加插入X
另外,題目說了是純字母的,可以通過轉成int陣列來解決。效能上應該能提升不少。習慣用通用解法,這裡編碼的時候就麼有寫。
按這個思路,其實自己覺得應該能挺快的。結果雖然不會超時,但是還是算不上一個好的解法:
程式碼如下:
class Solution {
public String reorganizeString(String S) {
// 將輸入拆分為字元陣列
String[] cArr = S.split("");
// 確定閾值
int origLength = S.length();
int max = origLength / 2 ;
if(origLength % 2 == 1) {
max = max + 1;
}
// 遍歷確定各元素個數
Map<String, Integer> hash = new HashMap<>();
int maxLength = 0;
// 用於記錄最大的key
String maxKey = cArr[0];
for(int i = 0; i < cArr.length; ++i) {
int currentSize = hash.getOrDefault(cArr[i], 0) + 1;
if(maxLength < currentSize) {
maxLength = currentSize;
maxKey = cArr[i];
}
hash.put(cArr[i], currentSize);
}
// 校驗是否滿足要求
if(maxLength > max) {
return "";
}
// 如果沒有溢位, 則生成符合要求的字串
// 將最大的key作為開始,遍歷所有元素生成滿足要求的字串
String maxKeyStr = maxKey;
char maxKeyChar = maxKey.charAt(0);
hash.remove(maxKeyStr);
String ret = "";
while(origLength-- > 0 && maxLength-- > 0) {
ret = ret+maxKey;
for(Map.Entry<String, Integer> entry : hash.entrySet()) {
if(entry.getValue() > 0) {
ret = ret + entry.getKey();
entry.setValue(entry.getValue() - 1);
origLength--;
}
}
// 如果hash裡的字母都寫完了,退出
if(origLength == maxLength) {
break;
}
}
// 遍歷完尚未清空最大陣列,將剩餘的maxKey插入結果中
StringBuilder sbRet=new StringBuilder(ret);
if(maxLength > 0) {
int i = 0;
while(maxLength-- > 0) {
// 如果插入位置左右都沒有maxKey,則後續都可以直接插入
while((i == 0 && sbRet.charAt(ret.length() - 1 - i) == maxKeyChar)
|| (i > 0 && (sbRet.charAt(ret.length() - 1 - i) == maxKeyChar || sbRet.charAt(ret.length() - 1 - i + 1) == maxKeyChar))) {
i++;
}
sbRet.insert(ret.length() - i++, maxKey);
}
}
return sbRet.toString();
}
}
三、題解
有些題解說先把X放在下標偶數位置,再隨意安插其他字元就可以得出解了,但是如果是aaaabbbbc
這種,a_a_a_a_
這樣安插完後,再隨意安插的話就有abacababb
,會出現重複的情況,這個還沒有get到題解的意思。
另外官方題解:重構字串看著可以說是比較權威了,值得研讀,先休息,明天學習下題解。
相關文章
- 日記9(程式碼重構)
- OJ刷題之《複製字串》字串
- 【刷題日記】leetcode-493 翻轉對LeetCode
- 力扣刷題-滑動視窗(字串)力扣字串
- 刷題筆記02筆記
- 刷題筆記03筆記
- BUU刷題記錄
- 記錄刷題日常
- 【刷題打卡】day1 - 字串string字串
- [程式設計師日記]16題了解OC字串程式設計師字串
- LeetCode刷題日記 416. 分割等和子集LeetCode
- 面試刷題偶有記錄面試
- noip刷題筆記1筆記
- [雜項] 刷題記錄
- Codeforces 刷題記錄
- cf刷題雜記(2)
- LeetCode 刷題筆記LeetCode筆記
- leetcode刷題筆記LeetCode筆記
- LeetCode刷題記錄LeetCode
- 軟考刷題記錄3
- 軟考刷題記錄5
- 劍指offer刷題記錄
- 「翻轉字串」python之leetcode刷題|004字串PythonLeetCode
- 字串做題筆記字串筆記
- 刷題記錄(C語言)01C語言
- leetcode刷題筆記605LeetCode筆記
- ctfshow刷題記錄-cry方向-1
- ctfshow刷題記錄-社工篇-1
- leetcode刷題記錄 661~LeetCode
- 7月18日刷題記錄 二分答案跳石頭遊戲Getting遊戲
- 《重構》讀書筆記筆記
- 重構讀書筆記筆記
- 【字串】 優雅的暴力——字串下的雜湊判重問題字串
- (刷題筆記)軟考中級資料庫 上午題筆記資料庫
- LeetCode刷題進階之重新排列字串(1528)LeetCode字串
- 查重字串字串
- 第五章 字串專題 ---------------- 5.1 題解:判斷字串有無重複字元字串字元
- 劍指Offer系列刷題筆記彙總筆記