LeetCode 767. 重構字符串

給定一個字符串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;
    }
};
相關文章
相關標籤/搜索