zoukankan      html  css  js  c++  java
  • 621. Task Scheduler

    You are given a char array representing tasks CPU need to do. It contains capital letters A to Z where each letter represents a different task. Tasks could be done without the original order of the array. Each task is done in one unit of time. For each unit of time, the CPU could complete either one task or just be idle.

    However, there is a non-negative integer n that represents the cooldown period between two same tasks (the same letter in the array), that is that there must be at least n units of time between any two same tasks.

    You need to return the least number of units of times that the CPU will take to finish all the given tasks.

    Example 1:

    Input: tasks = ["A","A","A","B","B","B"], n = 2
    Output: 8
    Explanation: 
    A -> B -> idle -> A -> B -> idle -> A -> B
    There is at least 2 units of time between any two same tasks.
    

    Example 2:

    Input: tasks = ["A","A","A","B","B","B"], n = 0
    Output: 6
    Explanation: On this case any permutation of size 6 would work since n = 0.
    ["A","A","A","B","B","B"]
    ["A","B","A","B","A","B"]
    ["B","B","B","A","A","A"]
    ...
    And so on.
    

    Example 3:

    Input: tasks = ["A","A","A","A","A","A","B","C","D","E","F","G"], n = 2
    Output: 16
    Explanation: 
    One possible solution is
    A -> B -> C -> A -> D -> E -> A -> F -> G -> A -> idle -> idle -> A -> idle -> idle -> A
    

    Constraints:

    • The number of tasks is in the range [1, 10000].
    • The integer n is in the range [0, 100].
    class Solution {
        public int leastInterval(char[] tasks, int n) {
            Map<Character, Integer> map = new HashMap();
            for(char c: tasks){
                map.put(c, map.getOrDefault(c, 0) + 1);
            }
            PriorityQueue<Integer> pq = new PriorityQueue<Integer>((a, b) -> b - a);
            pq.addAll(map.values());//decreasing order存放字母的频率
            
            int res = 0;
            int cycle = n+1;
            while(!pq.isEmpty()){
                List<Integer> tmp = new ArrayList();//存放当前用过的数
                int cur = 0;
                for (int i = 0; i < cycle; i++) {
                    if (!pq.isEmpty()) {
                        tmp.add(pq.poll());
                        cur++;
                    }
                }
                for(int i: tmp){
                    if(--i > 0) pq.offer(i);//一次一个数只能减1
                }
                res += pq.isEmpty() ? cur : cycle;//empty说明能用的数用完了,否则还要进行下一次,那这次就完成了一个full cycle,加上cycle
            }
            return res;
        }
    }

    先想到跟频率有关系,然后应该是跟最大频率的字母有关,毕竟要隔n个才能出下一个同样的字母。每一个cyle是n+1

    用priorityqueue存decreasing order的频率,然后每次在一个n+1循环中把频率最高的拿出来,一次循环之后把频率依次--,不为0的再进入queue,

    如果这次剩下的queue不为空,说明要形成一个满的cycle,所以res+=cycle,如果最后剩下的queue空了,就说明能用的用完了,加上cur即可,因为没有到n+1

  • 相关阅读:
    C#中String和string的区别
    .NET设计模式系列文章
    [python] 视频008
    [python]获取字符串类型
    【影评-转自豆瓣】疯狂原始人
    [python]文本处理1.2
    周末可以做的10件事
    [python]随机数
    [python] 字符串引用
    用户控件(.ascx)与<ul><li>以及<a>布局之小结
  • 原文地址:https://www.cnblogs.com/wentiliangkaihua/p/13217177.html
Copyright © 2011-2022 走看看