• [LeetCode] 358. Rearrange String k Distance Apart


    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 题目总结

  • 相关阅读:
    ERROR 1045 (28000): Access denied for user root@localhost (using password:
    MySQL: InnoDB 还是 MyISAM?
    PHP系统函数
    为什么分离数据库软件和数据库服务?
    C#索引器的作用及使用
    asp.net 中Session的运用,及抛出错误“未将对象引用设置到对象的实例”
    C#父类对象和子类对象之间的转化
    C#中属性简写原理
    c# 中Intern的作用
    C# 中ref和out的区别
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12695573.html
Copyright © 2020-2023  润新知