草庐IT

LeetCode——任务调度器

stepfortune 2023-03-28 原文

1. 任务调度器

这道题一上手会犯直接找模拟方法,然后根据模拟方法来得出结果。也不是说直接找模拟方法不对,只是说一开始没有更深入的思考的话,模拟方法很可能是错的,导致浪费时间,像这种题,要注意其中的极限思想,比如这道题,假如其他变量不动,把等待间隔不断调大会发生什么?然后出现变化的分界点是什么?按照这样思考,就不难出结果了。

题目链接

1.1. 问题

给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。然而,两个相同种类的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。你需要计算完成所有任务所需要的 最短时间 。

比如:
输入:tasks = ["A","A","A","B","B","B"], n = 2
输出:8
解释:A -> B -> (待命) -> A -> B -> (待命) -> A -> B
在本示例中,两个相同类型任务之间必须间隔长度为 n = 2 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。

输入:tasks = ["A","A","A","A","A","A","B","C","D","E","F","G"], n = 2
输出:16
解释:一种可能的解决方案是:
A -> B -> C -> A -> D -> E -> A -> F -> G -> A -> (待命) -> (待命) -> A -> (待命) -> (待命) -> A

1.2. 思路

这道题我一开始写错了。。。
这个是我的错误代码,对于AAABBBCCCDDE,n = 2,这种情况,我的代码中构造的任务调度方式为:ABC|ABC|ABC|DE |D,一共需要13个单位时间。
但实际上12个单位时间就够了。。。这明显是我任务调度方式安排的不对。。。

    //错误代码
    public static int leastInterval(char[] tasks, int n) {
        if (tasks == null) return 0;
        if (tasks.length < 2 || n == 0) return tasks.length;
        int bucketNum = 0;
        int fullNum = 0;
        int[] buckets = new int[tasks.length];
        int bucketSize = n + 1;
        int[] times = new int[26];
        for (int i = 0; i < tasks.length; i++) {
            times[tasks[i] - 'A']++;
        }

        for (int i = 0; i < 26; i++) {
            if (times[i] > 0) {
                int end = fullNum + times[i];
                for (int j = fullNum; j < Math.min(end, bucketNum); j++) {
                    if (++buckets[j] == bucketSize) {
                        fullNum++;
                    }
                }
                for (int j = bucketNum; j < end; j++) {
                    buckets[bucketNum++] = 1;
                }
            }
        }
        return (bucketNum - 1) * bucketSize + buckets[bucketNum - 1];
    }

这道题其实是个极限的思想,关键在于相同任务的执行时间间隔:

  1. 如果这个间隔足够大,那么这时,最小的执行时间就为(count[25] - 1)× (n+1)+ maxCount
  2. 如果这个间隔不够大,导致(count[25] - 1)×(n+1)+ maxCount小于taskTotalCount,那么可以通过某种方式证明,此时的执行时间为taskTotalCount

第二点证明如下:
在第二点的情况下,那么产生ceil(totalTaskCount / (n + 1))个时间间隔(因为此时(count[25] - 1) × (n + 1) + 1 < taskTotalCount,所以ceil(totalTaskCount / (n + 1))一定不小于count[25],然后将排序好的任务按照循环时间段的方式来填:

对于AAABBBCCCDDE,n = 2
---/---/---/---
A--/A--/A--/B--
AB-/AB-/AC-/BC-
ABC/ABD/ACD/BCE

按照这种方式来填的话,只有最后一个时间段才可能填不满,并且一定满足除了出现次数最多的任务的其他任务的时间间隔的需求:

  • ceil(totalTaskCount / (n + 1))count[25]相等:由于是次数多的任务先填,次数小的任务后填,所以不可能出现次数和count[25]相等的其他任务第一次填的时间段不是第一个时间段导致时间间隔不满足要求的情况。

  • ceil(totalTaskCount / (n + 1))大于count[25],那么很显然,每种任务的时间间隔要求都能满足。

    public int leastInterval(char[] tasks, int n) {
                int[] count = new int[26];
        for (int i = 0; i < tasks.length; i++) {
            count[tasks[i]-'A']++;
        }//统计词频
        Arrays.sort(count);//词频排序,升序排序,count[25]是频率最高的
        int maxCount = 0;
        //统计有多少个频率最高的字母
        for (int i = 25; i >= 0; i--) {
            if(count[i] != count[25]){
                break;
            }
            maxCount++;
        }
        //公式算出的值可能会比数组的长度小,取两者中最大的那个
        return Math.max((count[25] - 1) * (n + 1) + maxCount , tasks.length);

    }

有关LeetCode——任务调度器的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby - 如何使用 RSpec::Core::RakeTask 创建 RSpec Rake 任务? - 2

    如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake

  3. Python 刷Leetcode题库,顺带学英语单词(31) - 2

    ValidPalindromeGivenastring,determineifitisapalindrome,consideringonlyalphanumericcharactersandignoringcases. [#125]Example:"Aman,aplan,acanal:Panama"isapalindrome."raceacar"isnotapalindrome.Haveyouconsiderthatthestringmightbeempty?Thisisagoodquestiontoaskduringaninterview.Forthepurposeofthisproblem

  4. ruby-on-rails - Rake 任务仅调用一次时执行两次 - 2

    我写了一个非常简单的rake任务来尝试找到这个问题的根源。namespace:foodotaskbar::environmentdoputs'RUNNING'endend当在控制台中执行rakefoo:bar时,输出为:RUNNINGRUNNING当我执行任何rake任务时会发生这种情况。有没有人遇到过这样的事情?编辑上面的rake任务就是写在那个.rake文件中的所有内容。这是当前正在使用的Rakefile。requireFile.expand_path('../config/application',__FILE__)OurApp::Application.load_tasks这里

  5. ruby - 帮助使用 Ruby 中的 "Whenever"gem 来执行 cron 任务 - 2

    我以前没有使用过cron,所以我不能确定我这样做是对的。我想要自动化的任务似乎没有运行。我在终端中执行了这些步骤:sudogeminstall每当切换到应用程序目录无论何时。(这创建了文件schedule.rb)我将此代码添加到schedule.rb:every10.minutesdorunner"User.vote",environment=>"development"endevery:hourdorunner"Digest.rss",:environment=>"development"end我将此代码添加到deploy.rb:after"deploy:symlink","depl

  6. ruby - 在 rake 任务中运行 capybara - 2

    如何在Rake任务中运行Capybara功能?例如:访问('http://google.com')谢谢! 最佳答案 在任务中尝试这样的事情:require'capybara'require'capybara/dsl'Capybara.current_driver=:seleniumBrowser=Class.new{includeCapybara::DSL}page=Browser.new.pagepage.visit("http://www.google.com")puts(page.html)

  7. ruby - 在 Rakefile 中动态生成 Rake 测试任务(基于现有的测试文件) - 2

    我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n

  8. ruby-on-rails - 使用 Rspec 测试 rake 任务不接受参数 - 2

    根据thispostbyStephenHagemann,我正在尝试为我的一个rake任务编写Rspec测试.lib/tasks/retry.rake:namespace:retrydotask:message,[:message_id]=>[:environment]do|t,args|TextMessage.new.resend!(args[:message_id])endendspec/tasks/retry_spec.rb:require'rails_helper'require'rake'describe'retrynamespaceraketask'dodescribe're

  9. IDEA使用LeetCode插件 - 2

    前言我们习惯用idea编写、调试代码,在LeetCode上刷题时,如果能够在IDEA编写代码,并且做好代码管理,是一件事半功倍的事情。对于后续复习题目,做笔记也会非常便利。本文目的在于介绍LeetCodeEditor的使用,以及配置工具类,最终目录结构如下:note:放置笔记src:放置代码leetcode.editor.cn:插件LeetCodeEditor自动生成utils:自定义的工具包,可用于自动化输入测试用例,定义题目需要的类(结构体)out:运行测试时自动生成LeetCodeEditorGitHub:https://github.com/shuzijun/leetcode-edit

  10. ruby-on-rails - 在 gem 的 rake 任务中需要 gem - 2

    我正在使用jeweler为Rails3创建一个gem。该gem包含一个rake任务,它所做的其中一件事是删除数据库,所以我正在使用“database_cleaner”。我在gem的Gemfile中指定gem依赖项gem'database_cleaner'在Rakefile中Jeweler::Tasks.newdo|gem|...gem.add_dependency'database_cleaner'end然后在lib中我创建了文件my_gem.rb和tasks.rake。如下,my_gem.rb:moduleMyGemclassRailtie和tasks.rake:task:my_ta

随机推荐