首页 > 技术文章 > [LeetCode] 358. Rearrange String k Distance Apart

cnoodle 2020-04-14 08:13 原文

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 }

 

相关题目

358. Rearrange String k Distance Apart

767. Reorganize String

LeetCode 题目总结

推荐阅读