1. 程式人生 > 其它 >767. 重構字串

767. 重構字串

技術標籤:LeetCode雜湊表LeetCode字串字串資料結構leetcode

1.題目描述

給定一個字串S,檢查是否能重新排布其中的字母,使得兩相鄰的字元不同。
若可行,輸出任意可行的結果。若不可行,返回空字串。
示例 1:
在這裡插入圖片描述
示例 2:
在這裡插入圖片描述
注意:
S 只包含小寫字母並且長度在[1, 500]區間內。

2.思路

1.如果要使得兩相鄰的字元不同,那麼出現次數最多的那個數的數量必須滿足下面條件,如下圖所示,比如下面的a是出現次數最多的
在這裡插入圖片描述
2.這個時候a的數量已經達到了臨界值,如果再多一個 a ,那麼至少有兩個 a 是相鄰的。所以這裡出現次數最多的那個字元數量的臨界值是threshold = (length + 1) >> 1(其中 length 是字串的長度)

3.如果能使得兩相鄰的字元不同,我們可以先把出現次數最多的那個字元放到新字串下標為偶數的位置上,放完之後在用其他的字元填充字串剩下的位置。

3.程式碼

class Solution {
public:
    string reorganizeString(string S) {
        if(S.empty()){
            return "";
        }
        vector<int> m(26);
        int maxCount = 0, threshold = (S.size() + 1) >>
1; int maxChar = 0; //統計出現次數最多的字元 for(int i = 0; i < S.size(); ++i){ m[S[i] - 'a'] ++; if(m[S[i] - 'a'] > maxCount){ maxCount = m[S[i] - 'a']; maxChar = S[i] - 'a'; if(maxCount > threshold){ return
""; } } } string res(S.size(), '#'); //把次數最多的字元放到偶數位置 int index = 0; while(m[maxChar]-- > 0){ res[index] = (char)(maxChar + 'a'); index += 2; } //把其他字元放到其他位置 for(int i = 0; i < m.size(); ++i){ while(m[i]-- > 0){ if(index >= S.size()){ index = 1; } res[index] = (char)(i + 'a'); index += 2; } } return res; } };

4.複雜度分析

時間複雜度:O(n)
空間複雜度:O(1)