給定一個字符串S,檢查是否能從新排布其中的字母,使得兩相鄰的字符不一樣。數組
若可行,輸出任意可行的結果。若不可行,返回空字符串。網絡
示例 1:code
輸入: S = "aab"
輸出: "aba"
示例 2:blog
輸入: S = "aaab"
輸出: ""
注意:排序
S 只包含小寫字母而且長度在[1, 500]區間內。leetcode
來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/reorganize-string
著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。字符串
對字符串進行統計每個字符出現的次數。string
第一部分:先判斷可否從新排布,當一個字母出現的個數比字符串長度一半還要多時就沒法從新排布;io
第二部分:進行從新排列,最長爲500個,其實就能夠開闢一個數組(至關於挖好坑,等下把蘿蔔埋下去就能夠了),把同一字符間隔排序就行了:class
一、以字符出現的個數多少來決定先排布哪一個字符,舉個栗子:aaaiij,若是不先排a,先把i和j用了,iji,就還剩下兩個a,就沒法從新排布。
二、先排0、二、四、六、8...位置上的,當已經填滿一半時就能夠排一、三、五、7...
舉個栗子:aaaabbbbcccc
先排第一趟0、二、四、六、八、10:a_a_a_a_b_b_
接下來從一、三、五、七、9:ababacacbcbc
就完成了字符串的從新排列。
class Solution { public: string reorganizeString(string S) { int num[30],l,p1,p2,temp[505],k,flag; string res=""; fill(num,num+30,0); for (int i=0;i<S.length();i++){ num[S[i]-'a']++;//對每個字符進行統計出現的個數 } for (int i=0;i<26;i++){ if (num[i]>=(S.length()+1)/2+1){//當有字符出現次數大於通常就斷定爲沒法從新排列 return ""; } } l=0;//表明已完成從新排列的字符個數 p1 = -1;//記錄當前填入的字符(找到的出現的次數的字符) k=0;//當前填入到臨時數組的下標 flag=0;//用與表明還沒開始第二趟 while(l<S.length()){ if (l>=((S.length()+1)/2)&&flag==0){//當已填完通常的字符時,開始第二趟 k=1; flag=1; } if (p1==-1||num[p1]==0){//當前指向的字符已所有完成了從新排列,須要找尋下一個字符 for (int i=0;i<26;i++){ if (num[i]!=0){ p1=i; break; } } for (int i=0;i<26;i++){//找到出現次數最多的字符 if (num[i]>num[p1]){ p1 = i; } } } temp[k]=p1;//填入該字符到臨時數組中去 k+=2;//間隔填入 l++; num[p1]--; } for (int i=0;i<S.length();i++){//按數組的排列,從新得到字符串 res+=('a'+temp[i]); } return res; } };