[LeetCode] 358. Rearrange String k Distance Apart

Given a string s and an integer k, rearrange s such that the same characters are at least distance k from each other. 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 a distance of 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 a distance of 2 from each other.

Constraints:

  • 1 <= s.length <= 3 * 105
  • s consists of only lowercase English letters.
  • 0 <= k <= s.length

K 距离间隔重排字符串。

给你一个非空的字符串 s 和一个整数 k ,你要将这个字符串 s 中的字母进行重新排列,使得重排后的字符串中相同字母的位置间隔距离 至少 为 k 。如果无法做到,请返回一个空字符串 ""。

思路类似767题,也是会用到 hashmap 和 pq,pq 是一个 maxheap,hashmap 的 value 大的在堆顶。遍历 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 }

 

相关题目

358. Rearrange String k Distance Apart

767. Reorganize String

LeetCode 题目总结

posted @ 2020-04-14 08:13  CNoodle  阅读(755)  评论(0编辑  收藏  举报