LeetCode--Greedy

来源:互联网 发布:金兰营销软件 编辑:程序博客网 时间:2024/06/04 18:54

621. Task Scheduler(任务调度)

Given a char array representing tasks CPU need to do. It contains capital letters A to Z where different letters represent different tasks.Tasks could be done without original order. Each task could be done in one interval. For each interval, CPU could finish one task or just be idle.
However, there is a non-negative cooling interval n that means between two same tasks, there must be at least n intervals that CPU are doing different tasks or just be idle.
You need to return the least number of intervals the CPU will take to finish all the given tasks.

Example

Input: tasks = [‘A’,’A’,’A’,’B’,’B’,’B’], n = 2
Output: 8
Explanation: A -> B -> idle -> A -> B -> idle -> A -> B.

Note:

The number of tasks is in the range [1, 10000].
The integer n is in the range [0, 100].

解析:

仔细分析这道题,发现结果和任务的名字无关,只与任务的数量有关。
本题很明显可以使用贪心策略+优先队列
任务优先级按照任务数量从大到小进行排列。
每次从优先队列中选择优先级最高的任务执行,然后将其从队列中弹出,如果该任务的实例数量大于1,则将实例数量减1并暂存在一个临时list中,循环这个步骤直至任务冷却时间n过去,然后将list中的任务重新加入优先队列。按照上述步骤,循环,直到任务队列和临时list为空,表示所有任务执行完毕。

c++代码实现:

class Solution {public:    int leastInterval(vector<char>& tasks, int n) {        int m = tasks.size();        if(m<=1)    return m;        vector<int> dict(26,0);        for(char c : tasks)            dict[c-'A']++;        priority_queue<int,vector<int>,decltype(std::less<int>())> task_queue;  //从大到小        for(int i=0; i<26; i++) {            if(dict[i]!=0)                task_queue.push(dict[i]);          }        int t = 0;        while(!task_queue.empty()) {            int i = 0;            vector<int> temp;            while(i<=n) {       //冷却时间                if(!task_queue.empty()) {                    int task = task_queue.top();                    task_queue.pop();                    if(task > 1)                        temp.push_back(task-1);                 }                t++;                if(task_queue.empty() && temp.size()==0)                    break;                i++;            }            for(int a : temp)      //经过冷却时间后,将任务重新加入队列                task_queue.push(a);             }        return t;    }};

402. Remove K Digits

Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible.

Note:

The length of num is less than 10002 and will be ≥ k.
The given num does not contain any leading zero.

Example

(1) Input: num = “1432219”, k = 3
Output: “1219”
Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest.
(2) Input: num = “10200”, k = 1
Output: “200”
Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes.
(3) Input: num = “10”, k = 2
Output: “0”
Explanation: Remove all the digits from the number and it is left with nothing which is 0.

解析:

贪心法。removeKdigits(num, k) = removeKdigits(removeKdigits(num, 1), k-1)。每次从头开始找一位进行删除,进行K轮。
那么,选择哪一位进行删除呢?
(1)如果第2位是0,则删掉第1个数,会使得整个数量级下降2级。比如:10111–》111;
(2)否则,选择第一个下降的拐点,删除这个数,会使得数最小。比如:123546–》12346(删掉1位的情况下,删除5是最优选择)。

C++代码实现:

class Solution {public:    string removeKdigits(string num, int k) {        int n = 0;        while(true){            n = num.size();            if(n==0 || n<=k)    return "0";            if(k--==0)  return num;            if(num[1]=='0') {          //第二位是0,则删掉第一个可以减少两个数量级                int start = 1;                while( start < n && num[start]=='0')                    start++;                //找0之后的第一个非0数                num = num.substr(start);            }else {        //找到下降的点                int start = 0;                while(start < n-1 && num[start] <= num[start+1])                        start++;                num = num.substr(0,start) + num.substr(start+1);            }        }    }};
原创粉丝点击