import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class TaskScheduler {
    //方法一:模拟法
    public int leastInterval1(char[] tasks, int n) {
        //用hashmap进行统计每个任务出现的次数
        HashMap<Character, Integer> countMap = new HashMap<>();
        for (char task : tasks) {
            countMap.put(task,countMap.getOrDefault(task,0)+1);
        }

        //取当前任务种类数量
        int t = countMap.size();

        //定义两个状态列表
        ArrayList<Integer> restCount = new ArrayList<>(countMap.values());//任务剩余次数
        ArrayList<Integer> nextAvailableTime = new ArrayList<>(Collections.nCopies(t, 1));//任务下次可执行时间

        int time = 0;//模拟CPU时钟

        //遍历任务,选择执行
        for (int i = 0; i <tasks.length; i++) {
            time++;

            int minNextAvailableTime = Integer.MAX_VALUE;
            //1.获取所有任务中最早可执行的时间
            for (int j = 0; j <t ; j++) {
                //取还没做完的任务
                if(restCount.get(j)!=0){
                    minNextAvailableTime = Math.min(minNextAvailableTime,nextAvailableTime.get(j));
                }
            }

            //2.直接推进时间,执行任务
            time = Math.max(time,minNextAvailableTime);

            //3.选取可执行任务中,剩余次数最多的
            int maxRestCountTask = -1;//保存要执行任务的索引
            for (int j = 0; j <t ; j++) {
                if(restCount.get(j)>0&&nextAvailableTime.get(j)<=time){
                    //如果比之前保存的最大剩余任务数还大,就更新
                    if(maxRestCountTask==-1||restCount.get(j)>restCount.get(maxRestCountTask)){
                        maxRestCountTask = j;
                    }
                }
            }

            //4.执行任务,更新状态列表
            nextAvailableTime.set(maxRestCountTask,time+n+1);
            restCount.set(maxRestCountTask,restCount.get(maxRestCountTask)-1);
        }
        return time;
    }

    //方法二:构造法
    public int leastInterval(char[] tasks, int n) {
        //用hashmap进行统计每个任务出现的次数
        HashMap<Character, Integer> countMap = new HashMap<>();
        for (char task : tasks) {
            countMap.put(task,countMap.getOrDefault(task,0)+1);
        }

        //取当前任务种类数量
        int t = countMap.size();

        int maxCount = 0;
        int maxNum = 0;

        //1.计算maxCount
        for (int count : countMap.values()) {
            maxCount = Math.max(maxCount,count);
        }

        //2.计算maxNum
        for(char task:countMap.keySet()){
            if(countMap.get(task)==maxCount){
                maxNum++;
            }
        }

        //3.按照公式直接返回
        return Math.max(tasks.length,(maxCount-1)*(n+1)+maxNum);
    }

    public static void main(String[] args) {
        char[] tasks = {'A','A','A','B','B','B'};
        int n = 2;
        TaskScheduler taskScheduler = new TaskScheduler();
        System.out.println(taskScheduler.leastInterval(tasks,n));
    }
}