leetCode767 重構字串

2021-10-11 01:14:50 字數 1639 閱讀 4566

目錄

一、題目描述

二、解題思路

三、**實現

給定乙個字串s,檢查是否能重新排布其中的字母,使得兩相鄰的字元不同。

若可行,輸出任意可行的結果。若不可行,返回空字串。

示例 1:

輸入:s = "aab"

輸出:"aba"

示例 2:

輸入:s = "aaab"

輸出:""

注意:

可以先直觀經驗考慮這道題,應該能想到插空法,就是在兩個相同的字元之間插入乙個不同的字元。那就會想到統計每種字元的出現次數,然後給他們安排位置,基本上這道題的大概思路就有了。

貪心插空,注意需要按照字元出現的次數考慮放在奇數還是偶數下標上。

可以使用反證法,證明當乙個字元先出現在奇數字上然後在出現在偶數字上時,不會出現相鄰的情況。

由於先出現在奇數字上,那麼個數小於或等於 n/2,一旦相鄰則長度至少為(n+1)/2,相互矛盾。

另外在題解區看見一位大佬的另一種更為直接的思路:按照字元出現的次數先從小到大排序,排序之後從次數少的字元開始直接往奇數字置上放,奇數字置放滿了之後再往偶數字上放,這樣可以不用在迴圈裡做額外的判斷就能保證次數等於 (n+1)/2的字元會出現在偶數字上。

#includeusing namespace std;

string reorganizestring(string s)

if (maxcnt > (n + 1) / 2) return "";

string res(n, ' ');

int evenindex = 0, oddindex = 1;

int halfnums = n / 2;

//對字元進行重排

for (int i = 0; i < 26; ++i)

//如果長度等於一半或者一半加一,或者奇數下標已經用完了,就用偶數下標

while (chvec[i] > 0)

} return res;

}//這個思路好操作一些:按照出現次數從小到大排序之後,只要依次往奇數下標上放就行,奇數用完了再用偶數下標

//由於統計字元次數的陣列會被排序打亂,所以要把字元和出現次數資訊都記錄在陣列中

//這個陣列很妙啊

string reorganizestring1(string s)

for (int i = 0; i < 26; ++i) count[i] += i; // 將字元資訊加入陣列值中

// 此時count中的元素儲存了次數和字元資訊

// 如 count[i] = 203 表示字元 'd'='a'+203%100 出現了 2=203/100 次

sort(count.begin(), count.end()); // 對次數從小到大排序

int index = 1;

string ret(n, ' ');

for (auto c : count)

} return ret;

}int main()

Leetcode 767 重構字串

給定乙個字串s,檢查是否能重新排布其中的字母,使得兩相鄰的字元不同。若可行,輸出任意可行的結果。若不可行,返回空字串。示例 1 輸入 s aab 輸出 aba 示例 2 輸入 s aaab 輸出 注意 解題思路 任務排程問題,排序。本題有點像之前的乙個任務排程問題,由於題量太大,忘了哪乙個。統計當前...

leetcode 767 重構字串

描述 給定乙個字串s,檢查是否能重新排布其中的字母,使得兩相鄰的字元不同。若可行,輸出任意可行的結果。若不可行,返回空字串。示例 1 輸入 s aab 輸出 aba 示例 2 輸入 s aaab 輸出 注意 s 只包含小寫字母並且長度在 1,500 區間內。思路從小到大,交叉著插入 bool cmp...

LeetCode 767 重構字串

給定乙個字串s,檢查是否能重新排布其中的字母,使得兩相鄰的字元不同。若可行,輸出任意可行的結果。若不可行,返回空字串。示例 1 輸入 s aab 輸出 aba 示例 2 輸入 s aaab 輸出 注意 s 只包含小寫字母並且長度在 1,500 區間內。通過次數13,259 提交次數30,089思路 ...