leetcode621.任务调度器

一.按照词频求
参考:https://blog.csdn.net/qq_26410101/article/details/82108011
http://www.javashuo.com/article/p-kshmntzb-ne.html (公式里少写了括号)web

我的理解:
(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
上面的博客有解析svg