Given a non-empty string s and an integer k, rearrange the string such that the same characters are at least distance k from each other.
All input strings are given in lowercase letters. If it is not possible to rearrange the string, return an empty string ""
.
Example 1:
Input: s = "aabbcc", k = 3 Output: "abcabc" Explanation: The same letters are at least distance 3 from each other.
Example 2:
Input: s = "aaabc", k = 3 Output: "" Explanation: It is not possible to rearrange the string.
Example 3:
Input: s = "aaadbbcc", k = 2 Output: "abacabcd" Explanation: The same letters are at least distance 2 from each other.
K距离间隔重排字符串。
给你一个非空的字符串 s 和一个整数 k,你要将这个字符串中的字母进行重新排列,使得重排后的字符串中相同字母的位置间隔距离至少为 k。所有输入的字符串都由小写字母组成,如果找不到距离至少为 k 的重排结果,请返回一个空字符串 ""。
思路类似767题,也是会用到hashmap和pq,pq存的是一个maxheap,hashmap的value大的在heap顶端。遍历input,用hashmap统计每个字符串的出现次数,将出现次数大于0的字符串放入heap,出现次数相同的则会按照字母顺序排列。之后开始从heap中弹出元素(同时需要用一个list记录弹出的元素,因为你需要这个list再把弹出但是mapvalue不为0的元素再放回maxheap),弹出的元素需要加到stringbuilder。因为要保持相同字母距离为K的关系,所以在弹出的过程中如果heap空了,需要判断此时i是否到达K了或者已经拼接好的部分和原字符串是否等长。这样可以规避掉比如第二个例子这样的corner case,否则这个case的输出会是"abcaa"。
时间O(nlogn)
空间O(n)
Java实现
1 class Solution { 2 public String rearrangeString(String s, int k) { 3 // corner case 4 if (k <= 1 || s.length() < k) { 5 return s; 6 } 7 8 // normal case 9 int[] map = new int[26]; 10 for (int i = 0; i < s.length(); i++) { 11 map[s.charAt(i) - 'a']++; 12 } 13 PriorityQueue<int[]> heap = new PriorityQueue<>((a, b) -> a[1] == b[1] ? a[0] - b[0] : b[1] - a[1]); 14 StringBuilder sb = new StringBuilder(); 15 for (int i = 0; i < 26; i++) { 16 if (map[i] > 0) { 17 heap.offer(new int[] { i, map[i] }); 18 } 19 } 20 while (!heap.isEmpty()) { 21 List<Integer> list = new ArrayList<>(); 22 for (int i = 0; i < k; i++) { 23 int[] cur = heap.poll(); 24 sb.append((char) (cur[0] + 'a')); 25 list.add(cur[0]); 26 if (heap.size() == 0) { 27 if (i != k - 1 && s.length() != sb.length()) { 28 return ""; 29 } 30 break; 31 } 32 } 33 for (int i : list) { 34 if (--map[i] > 0) { 35 heap.offer(new int[] { i, map[i] }); 36 } 37 } 38 } 39 return sb.toString(); 40 } 41 }
相关题目