leetcode621.任务调度器

一.按照词频求
参考:https://blog.csdn.net/qq_26410101/article/details/82108011
https://blog.csdn.net/qq_38595487/article/details/79977315 (公式里少写了括号)

个人理解:
(1)先找出现次数最多的字母,假设为A,出现m次,要求字母间隔大于n。那么先将A按照给定间隔排好后的长度为(m-1)*(n+1) + 1,(m-1)是因为m个A之间有(m-1)块空格。(n+1)是因为每块空格长度为n,在加上字母A,一共n+1,最后一个+1是最后一个字母A。比如字母A出现3次,间隔为2,则A排好后为
A _ _ A _ _ A
(2)接下来排的时候只需要依次将频率小的字母插入这些空格中,注意插的时候要先插满第二位的空格,再插第三位的空格,以此类推,且频率高的字母先插。
(3)上面说的是大部分情况,但是还会出现两种特殊情况:
1.最大频率的字母不止一个,比如A,B都出现了3次,则此时A,B排好后为AB _ _ AB _ _ AB
会发现此时长度多了一个长度(最后一个B的长度),因此此时的总长度应该为(m-1)*(n+1)+count ,count为最大频率的字母个数,在这里为2。上面的(1)可以认为是count=1的一个特例
2.当中间所有的空格都被填满了还没有插入所有元素,此时需要将剩余元素依次插入到每块的后面去(这样可以保证彼此间的间隔大于n,相当于是拓宽了部分块的间隔),比如AAABBCCD 先得到ABCABCA,此时还有一个D没有插入,则插到每个块后面去,得到ABCDABCA,此时会发现其实这个长度就是原数组的长度。

class Solution {
public:
    int leastInterval(vector<char>& tasks, int n) {
        unordered_map<char,int>mp; //值为字母,键为出现的次数
        int count = 0;
        for(auto e : tasks)
        {
            mp[e]++;   //记录每个字母的次数
            count = max(count, mp[e]); //记录出现最多的次数
        }
        
        int ans = (count-1)*(n+1); //第(1)种情况
        for(auto e : mp) if(e.second == count) ans++;//第(3)-1的情况,第一种中的+1是在这里加的
        return max((int)tasks.size(), ans); //第(3)-2的情况
    }
};

二优先队列(没看)
https://leetcode.com/problems/task-scheduler/discuss/104493/C%2B%2B-Java-Clean-Code-Priority-Queue
上面的博客有解析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值