767. 重构字符串
给定一个字符串 s
,检查是否能重新排布其中的字母,使得两相邻的字符不同。
返回 s
的任意可能的重新排列。若不可行,返回空字符串 ""
。
示例 1:
输入: s = "aab" 输出: "aba"
示例 2:
输入: s = "aaab" 输出: ""
提示:
1 <= s.length <= 500
s
只包含小写字母原站题解
java 解法, 执行用时: 0 ms, 内存消耗: 39.6 MB, 提交时间: 2023-06-13 14:26:22
class Solution { public String reorganizeString(String S) { //把字符串S转化为字符数组 char[] alphabetArr = S.toCharArray(); //记录每个字符出现的次数 int[] alphabetCount = new int[26]; //字符串的长度 int length = S.length(); //统计每个字符出现的次数 for (int i = 0; i < length; i++) { alphabetCount[alphabetArr[i] - 'a']++; } int max = 0, alphabet = 0, threshold = (length + 1) >> 1; //找出出现次数最多的那个字符 for (int i = 0; i < alphabetCount.length; i++) { if (alphabetCount[i] > max) { max = alphabetCount[i]; alphabet = i; //如果出现次数最多的那个字符的数量大于阈值,说明他不能使得 // 两相邻的字符不同,直接返回空字符串即可 if (max > threshold) return ""; } } //到这一步说明他可以使得两相邻的字符不同,我们随便返回一个结果,res就是返回 //结果的数组形式,最后会再转化为字符串的 char[] res = new char[length]; int index = 0; //先把出现次数最多的字符存储在数组下标为偶数的位置上 while (alphabetCount[alphabet]-- > 0) { res[index] = (char) (alphabet + 'a'); index += 2; } //然后再把剩下的字符存储在其他位置上 for (int i = 0; i < alphabetCount.length; i++) { while (alphabetCount[i]-- > 0) { if (index >= res.length) { index = 1; } res[index] = (char) (i + 'a'); index += 2; } } return new String(res); } }
java 解法, 执行用时: 0 ms, 内存消耗: 39.5 MB, 提交时间: 2023-06-13 14:25:43
class Solution { public String reorganizeString(String s) { if (s.length() < 2) { return s; } int[] counts = new int[26]; int maxCount = 0; int length = s.length(); for (int i = 0; i < length; i++) { char c = s.charAt(i); counts[c - 'a']++; maxCount = Math.max(maxCount, counts[c - 'a']); } if (maxCount > (length + 1) / 2) { return ""; } char[] reorganizeArray = new char[length]; int evenIndex = 0, oddIndex = 1; int halfLength = length / 2; for (int i = 0; i < 26; i++) { char c = (char) ('a' + i); while (counts[i] > 0 && counts[i] <= halfLength && oddIndex < length) { reorganizeArray[oddIndex] = c; counts[i]--; oddIndex += 2; } while (counts[i] > 0) { reorganizeArray[evenIndex] = c; counts[i]--; evenIndex += 2; } } return new String(reorganizeArray); } }
golang 解法, 执行用时: 0 ms, 内存消耗: 1.8 MB, 提交时间: 2023-06-13 14:25:28
func reorganizeString(s string) string { n := len(s) if n <= 1 { return s } cnt := [26]int{} maxCnt := 0 for _, ch := range s { ch -= 'a' cnt[ch]++ if cnt[ch] > maxCnt { maxCnt = cnt[ch] } } if maxCnt > (n+1)/2 { return "" } ans := make([]byte, n) evenIdx, oddIdx, halfLen := 0, 1, n/2 for i, c := range cnt[:] { ch := byte('a' + i) for c > 0 && c <= halfLen && oddIdx < n { ans[oddIdx] = ch c-- oddIdx += 2 } for c > 0 { ans[evenIdx] = ch c-- evenIdx += 2 } } return string(ans) }
python3 解法, 执行用时: 60 ms, 内存消耗: 16.1 MB, 提交时间: 2023-06-13 14:25:12
# 基于计数的贪心 class Solution: def reorganizeString(self, s: str) -> str: if len(s) < 2: return s length = len(s) counts = collections.Counter(s) maxCount = max(counts.items(), key=lambda x: x[1])[1] if maxCount > (length + 1) // 2: return "" reorganizeArray = [""] * length evenIndex, oddIndex = 0, 1 halfLength = length // 2 for c, count in counts.items(): while count > 0 and count <= halfLength and oddIndex < length: reorganizeArray[oddIndex] = c count -= 1 oddIndex += 2 while count > 0: reorganizeArray[evenIndex] = c count -= 1 evenIndex += 2 return "".join(reorganizeArray)
javascript 解法, 执行用时: 64 ms, 内存消耗: 42.4 MB, 提交时间: 2023-06-13 14:24:52
const getIdx = (c) => c.charCodeAt() - 'a'.charCodeAt(); const getAlpha = (c) => String.fromCharCode(c); /** * @param {string} s * @return {string} */ var reorganizeString = function(s) { if (s.length < 2) { return s; } const counts = new Array(26).fill(0); let maxCount = 0; const length = s.length; for (let i = 0; i < length; i++) { const c = s.charAt(i); counts[getIdx(c)]++; maxCount = Math.max(maxCount, counts[getIdx(c)]); } if (maxCount > Math.floor((length + 1) / 2)) { return ""; } const reorganizeArray = new Array(length); let evenIndex = 0, oddIndex = 1; const halfLength = Math.floor(length / 2); for (let i = 0; i < 26; i++) { const c = getAlpha('a'.charCodeAt() + i); while (counts[i] > 0 && counts[i] <= halfLength && oddIndex < length) { reorganizeArray[oddIndex] = c; counts[i]--; oddIndex += 2; } while (counts[i] > 0) { reorganizeArray[evenIndex] = c; counts[i]--; evenIndex += 2; } } return reorganizeArray.join(''); };
python3 解法, 执行用时: 52 ms, 内存消耗: 16.1 MB, 提交时间: 2023-06-13 14:23:54
class Solution: def reorganizeString(self, s: str) -> str: if len(s) < 2: return s length = len(s) counts = collections.Counter(s) maxCount = max(counts.items(), key=lambda x: x[1])[1] if maxCount > (length + 1) // 2: return "" queue = [(-x[1], x[0]) for x in counts.items()] heapq.heapify(queue) ans = list() while len(queue) > 1: _, letter1 = heapq.heappop(queue) _, letter2 = heapq.heappop(queue) ans.extend([letter1, letter2]) counts[letter1] -= 1 counts[letter2] -= 1 if counts[letter1] > 0: heapq.heappush(queue, (-counts[letter1], letter1)) if counts[letter2] > 0: heapq.heappush(queue, (-counts[letter2], letter2)) if queue: ans.append(queue[0][1]) return "".join(ans)
golang 解法, 执行用时: 0 ms, 内存消耗: 1.8 MB, 提交时间: 2023-06-13 14:23:34
var cnt [26]int type hp struct{ sort.IntSlice } func (h hp) Less(i, j int) bool { return cnt[h.IntSlice[i]] > cnt[h.IntSlice[j]] } func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) } func (h *hp) Pop() interface{} { a := h.IntSlice; v := a[len(a)-1]; h.IntSlice = a[:len(a)-1]; return v } func (h *hp) push(v int) { heap.Push(h, v) } func (h *hp) pop() int { return heap.Pop(h).(int) } func reorganizeString(s string) string { n := len(s) if n <= 1 { return s } cnt = [26]int{} maxCnt := 0 for _, ch := range s { ch -= 'a' cnt[ch]++ if cnt[ch] > maxCnt { maxCnt = cnt[ch] } } if maxCnt > (n+1)/2 { return "" } h := &hp{} for i, c := range cnt[:] { if c > 0 { h.IntSlice = append(h.IntSlice, i) } } heap.Init(h) ans := make([]byte, 0, n) for len(h.IntSlice) > 1 { i, j := h.pop(), h.pop() ans = append(ans, byte('a'+i), byte('a'+j)) if cnt[i]--; cnt[i] > 0 { h.push(i) } if cnt[j]--; cnt[j] > 0 { h.push(j) } } if len(h.IntSlice) > 0 { ans = append(ans, byte('a'+h.IntSlice[0])) } return string(ans) }
java 解法, 执行用时: 2 ms, 内存消耗: 39.6 MB, 提交时间: 2023-06-13 14:23:13
// 基于最大堆的贪心 class Solution { public String reorganizeString(String s) { if (s.length() < 2) { return s; } int[] counts = new int[26]; int maxCount = 0; int length = s.length(); for (int i = 0; i < length; i++) { char c = s.charAt(i); counts[c - 'a']++; maxCount = Math.max(maxCount, counts[c - 'a']); } if (maxCount > (length + 1) / 2) { return ""; } PriorityQueue<Character> queue = new PriorityQueue<Character>(new Comparator<Character>() { public int compare(Character letter1, Character letter2) { return counts[letter2 - 'a'] - counts[letter1 - 'a']; } }); for (char c = 'a'; c <= 'z'; c++) { if (counts[c - 'a'] > 0) { queue.offer(c); } } StringBuffer sb = new StringBuffer(); while (queue.size() > 1) { char letter1 = queue.poll(); char letter2 = queue.poll(); sb.append(letter1); sb.append(letter2); int index1 = letter1 - 'a', index2 = letter2 - 'a'; counts[index1]--; counts[index2]--; if (counts[index1] > 0) { queue.offer(letter1); } if (counts[index2] > 0) { queue.offer(letter2); } } if (queue.size() > 0) { sb.append(queue.poll()); } return sb.toString(); } }