zoukankan      html  css  js  c++  java
  • [LeetCode] 358. Rearrange String k Distance Apart 按距离为k隔离重排字符串

    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.

    Credits:
    Special thanks to @elmirap for adding this problem and creating all test cases.

    这道题给了我们一个字符串str,和一个整数k,让我们对字符串str重新排序,使得其中相同的字符之间的距离不小于k,这道题的难度标为Hard,看来不是省油的灯。的确,这道题的解法用到了哈希表,堆,和贪婪算法。这道题我最开始想的算法没有通过OJ的大集合超时了,下面的方法是参考网上大神的解法,发现十分的巧妙。我们需要一个哈希表来建立字符和其出现次数之间的映射,然后需要一个堆来保存这每一堆映射,按照出现次数来排序。然后如果堆不为空我们就开始循环,我们找出k和str长度之间的较小值,然后从0遍历到这个较小值,对于每个遍历到的值,如果此时堆为空了,说明此位置没法填入字符了,返回空字符串,否则我们从堆顶取出一对映射,然后把字母加入结果res中,此时映射的个数减1,如果减1后的个数仍大于0,则我们将此映射加入临时集合v中,同时str的个数len减1,遍历完一次,我们把临时集合中的映射对由加入堆中,参见代码如下:

    class Solution {
    public:
        string rearrangeString(string str, int k) {
            if (k == 0) return str;
            string res;
            int len = (int)str.size();
            unordered_map<char, int> m;
            priority_queue<pair<int, char>> q;
            for (auto a : str) ++m[a];
            for (auto it = m.begin(); it != m.end(); ++it) {
                q.push({it->second, it->first});
            }
            while (!q.empty()) {
                vector<pair<int, int>> v;
                int cnt = min(k, len);
                for (int i = 0; i < cnt; ++i) {
                    if (q.empty()) return "";
                    auto t = q.top(); q.pop();
                    res.push_back(t.second);
                    if (--t.first > 0) v.push_back(t);
                    --len;
                }
                for (auto a : v) q.push(a);
            }
            return res;
        }
    };

    类似题目:

    Task Scheduler

    参考资料:

    https://leetcode.com/problems/rearrange-string-k-distance-apart/

    https://leetcode.com/discuss/108174/c-unordered_map-priority_queue-solution-using-cache

    LeetCode All in One 题目讲解汇总(持续更新中...)

  • 相关阅读:
    repeater嵌套RadioButtonList赋值
    hive表导出到mysql报错
    hive创建表时报错
    linux————mysql————修改密码
    Spark入门:Spark运行架构(Python版)
    1、Spark简介(Python版)
    使用蒙特 ·卡罗方法计算圆周率近似值
    python运算符,内置函数简单使用
    numpy、pandas、scipy、matplotlib、jieba、 openpyxl、pillow的安装
    XML详解
  • 原文地址:https://www.cnblogs.com/grandyang/p/5586009.html
Copyright © 2011-2022 走看看