25 力扣热题刷题记录之第621题任务调度器

系列文章目录

力扣热题刷题记录

前言

每天进步一点点!!

一、背景

简单描述一下题目,就是有许多任务,任务之间最短间隔是n,问如何安排任务使得时间最短?
在这里插入图片描述

来源:力扣
链接:https://leetcode-cn.com/problems/task-scheduler/

二、我的思路

我的思路是模拟任务调度,但是很复杂,我失败了,搞不下去了,烦死掉!!

目前通过了62个用例,唉,示范一下错误代码:

class Solution {
public:
    int leastInterval(vector<char>& tasks, int n) {
        int record[26]={0};
        int needs=0;

        if (n==0) return tasks.size();
        //统计字母个数
        for (int i=0 ; i< tasks.size() ; i++ )
        {
            record [ tasks[i]-'A' ] +=1;
        }
        vector<int > my_vec;
        for (int i=0;i<26&&record[i]>0;i++)
        {
            my_vec.push_back(record[i]);
        }      
        sort(my_vec.begin(),my_vec.end());//从小到大排序
        int count_kind=my_vec.size();//字母的类别
        int space_count=-1;//记录空几个再次填这个字母
        int count_zero=0;//统计哪些任务被分配完了

        //先分配高频的任务
    int i=0;
    for (i=count_kind-1;i>=0&&count_zero!=count_kind;i--)
    {
        if(my_vec[i]>0)
        {
            my_vec[i]--;
            if(my_vec[i]==0)
            {
                count_zero++;
            }

            needs++;//需要的时间增加
            space_count++;
            }
            if (space_count==n&&count_zero!=count_kind)
            {
                int j=count_kind-1;
                while(my_vec[j]<=0)
                {
                    j--;
                }
                my_vec[j]--;//让最大的出
                if(my_vec[j]==0)
                {
                    count_zero++;
                }
                needs++;//需要的时间增加
                space_count=0;
                if(i==0)
                    i=count_kind-1;//让它回到倒数第二个高频的位置
            }
            else if (i==0&&space_count<n&&count_zero!=count_kind)//表示还没结束
            {
                //cout<<"if前的i: "<<i<<" 和每一轮的needs:  "<<needs<<"  count_zero: "<<count_zero<<endl;
                needs+=n-space_count;//需要的时间增加
                i=count_kind-1+1 ;//因为for循环会自动减一,所以要加回来,这里希望的是回到最高频的那个词继续分配
                space_count=-1;
            }

                
            }
        return needs;
    }
};

在这里插入图片描述

三、官方的思路

1.模拟调度(不想看)

唉,一直是一大堆的证明啥的,不如方法二好理解!!!

2.公式法

考虑频率最高的那个任务,如果这个任务都被安排了,其它的任务插空就好了。

公式给出:count[25]指的是这个人程序里面的一个变量,意思是任务数最多的那个任务的数量。
在这里插入图片描述
代码如下:

class Solution {
public:
    int leastInterval(vector<char>& tasks, int n) {
        int maxcount=0;//记录最高词频一样的有几个
        int count=0;//记录最高词频
        map<char,int> my_map;//统计词频
        for (int i=0; i < tasks.size(); i++ )
        {
            my_map[ tasks[i] ]+=1;
            count=max ( count, my_map[ tasks[i] ]);
        }
        for (auto j=my_map.begin();j!=my_map.end();j++)
        {
            if(j->second==count)
                maxcount++;//统计最大的有几个
        }
        int ans=(count-1)*(n+1)+maxcount;
        //公式算出的可能比数组长度小,取大的那个
        ans=max(ans,int(tasks.size()));
        return ans;
    }
};

注意最后取最大的那个,是因为公式会计算出比数组长度小的值,比如n=0的时候。

注意下面这行代码,由于task.size()返回的类型严格意义上不是int型,而是一种size_type类型,所以这里转换为int类型,方便使用max函数比较。如果不使用,会报错说没有匹配的max函数(参数类型不一致导致无法匹配)。

ans=max(ans,int(tasks.size()));

总结

耐心被消磨,虐我!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值