LeetCode -- 767. 重构字符串
设字符串s长度为len
s可以重构为相邻字符串不同时 有字符串中出现次数最多的字符 < (len + 1) >> 1
当满足上述条件时候,我们就能对其进行重构
重构法:先放置偶数位置,再放置奇数位置
c ++ class Solution { public: string reorganizeString(string s) { vector<int> cnt(26, 0); int n = s.size(); for(int i = 0; i < n; i ++ ) { cnt[s[i] - 'a'] ++ ; } int mx = 0, alp = 0, lim = (n + 1) >> 1; for(int i = 0; i < 26; i ++ ) { if(cnt[i] > mx) { mx = cnt[i]; alp = i; } } if(mx > lim) return ""; string res(n, ' '); int idx = 0; while(cnt[alp] -- > 0) { res[idx] = 'a' + alp; idx += 2; } for(int i = 0; i < 26; i ++ ) { while(cnt[i] -- > 0) { if(idx >= n) { idx = 1; } res[idx] = 'a' + i; idx += 2; } } return res; } };
js代码,先把最多的放到答案中,再依次插入。
js /** * @param {string} s * @return {string} */ function getIdx(c) { return c.charCodeAt() - 'a'.charCodeAt(); } function getChar(c) { return String.fromCharCode(c + 'a'.charCodeAt()); } var reorganizeString = function(s) { let n = s.length let cnt = new Array(26).fill(0); for(let i = 0; i < n; i ++ ) { let it = cnt[getIdx(s[i])]; if(it) { it.count ++ ; } else { cnt[getIdx(s[i])] = {name:s[i],count:1}; } } cnt = cnt.filter((v) => { return v != 0; }); cnt.sort((a, b) => { return b.count - a.count; }); if(cnt[0].count > Math.floor((n + 1) / 2)) { return ""; } let res = new Array(cnt[0].count).fill(cnt[0].name); let idx = 1; for(let i = 1; i < cnt.length;) { res.splice(idx, 0, cnt[i].name); cnt[i].count -- ; if(cnt[i].count === 0) { i ++ ; } idx = idx + 2 > res.length ? 1: idx + 2; } return res.join("") };
解法二:利用桶(分组分类)思想
思路 1. 将相同的字符放入不同的桶中以保证其彼此不会相邻,因此桶的数目应等于字符串中最多的元素的数目; 2. 按贪心策略,优先填充数目最多的元素,对于每一种元素,循环在不同桶中进行填充,由于桶的个数等于字符串中最多的元素的数目,因此每个桶中不会出现相同的元素,填充完毕后将桶依次相连即为答案; 3. 若填充完毕后长度为1的桶(只可能出现在最后的位置)的数目多于1,将桶依次相连会使得这些长度为1的桶中的相同元素相邻,说明不存在相应的排列,返回""(这一情况即官解中说明的如果存在一个字母的出现次数大于(n+1)/2,其中n为字符串长度,则无法重新排布字母使得相邻的字母都不相同)。
c ++ class Solution { public: string reorganizeString(string s) { vector<int> cnt(26); int n = s.size(); for(int i = 0; i < n; i ++ ) { cnt[s[i] - 'a'] ++ ; } int mx = -1, pos = -1, lim = n + 1 >> 1; for(int i = 0; i < cnt.size(); i ++ ) { if(cnt[i] > mx) { mx = cnt[i]; pos = i; } } if(mx > lim) return ""; //初始化桶,将最多的元素放进去 vector<string> buf(mx); for(int i = 0; i < cnt[pos]; i ++ ) { buf[i] += 'a' + pos; } cnt[pos] = 0; int idx = 0; for(int i = 0; i < 26; i ++ ) { for(int j = 0; j < cnt[i]; j ++ ) { buf[idx] += 'a' + i; idx = (idx + 1) % mx; } } string res; for(int i = 0; i < mx; i ++ ) { res += buf[i]; } return res; } };
python class Solution: def reorganizeString(self, s: str) -> str: cnt, idx = Counter(s), 0 bufnum = cnt.most_common(1)[0][1] if bufnum > (len(s) + 1) // 2: return "" buckets = [[] for _ in range(bufnum)] for c, num in cnt.most_common(): for _ in range(num): buckets[idx].append(c) idx = (idx + 1) % bufnum return "".join(["".join(bucket) for bucket in buckets])
java class Solution { public String reorganizeString(String s) { int n = s.length(); int[] cnt = new int[26]; for(int i = 0; i < n; i ++ ) { char c = s.charAt(i); cnt[c - 'a'] ++ ; } int mx = -1, pos = -1, lim = n + 1 >> 1; for(int i = 0; i < 26; i ++ ) { if(cnt[i] > mx) { mx = cnt[i]; pos = i; } } if(mx > lim) return ""; int idx = 0; StringBuilder[] buf = new StringBuilder[mx]; for(int i = 0; i < mx; i ++ ) { buf[i] = new StringBuilder(); } for(int i = 0; i < mx; i ++ ) { buf[i].append((char)(pos + 'a')); } cnt[pos] = 0; for(int i = 0; i < 26; i ++ ) { for(int j = 0; j < cnt[i]; j ++ ) { buf[idx].append((char)('a' + i)); idx = (idx + 1) % mx; } } StringBuilder res = new StringBuilder(); Arrays.stream(buf).forEach((ss) -> { res.append(ss); }); return res.toString(); } }
golang func reorganizeString(s string) string { cnt := make(map[byte]int) mx := 0 n := len(s) for i := 0; i < n; i ++ { cnt[s[i]] ++ ; } chars := []byte{} for char, _ := range cnt { chars = append(chars, char) } sort.Slice(chars, func(i int, j int) (bool) {return cnt[chars[i]] > cnt[chars[j]]}) lim := (n + 1) / 2 mx = cnt[chars[0]] if(mx > lim) { return "" } buf := make([][]byte, mx) idx := 0 for _, ch := range chars { for i := 0; i < cnt[ch]; i ++ { buf[idx] = append(buf[idx], ch) idx = (idx + 1) % mx } } res := "" for i := 0; i < mx; i ++ { res += string(buf[i]) } return res }
分类:
lc练习
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)