leetcode之贪心算法



455. Assign Cookies
Assume you are an awesome parent and want to give your children some cookies. But, you should give each child at most one cookie. Each child i has a greed factor g i, which is the minimum size of a cookie that the child will be content with; and each cookie j has a size s j. If s j >= g i, we can assign the cookie j to the child i, and the child i will be content. Your goal is to maximize the number of your content children and output the maximum number.

Note:

You may assume the greed factor is always positive. 
You cannot assign more than one cookie to one child.

Example 1:

Input: [1,2,3], [1,1]

Output: 1

Explanation: You have 3 children and 2 cookies. The greed factors of 3 children are 1, 2, 3. 
And even though you have 2 cookies, since their size is both 1, you could only make the child whose greed factor is 1 content.
You need to output 1.

Example 2:

Input: [1,2], [1,2,3]

Output: 2

Explanation: You have 2 children and 3 cookies. The greed factors of 2 children are 1, 2. 
You have 3 cookies and their sizes are big enough to gratify all of the children, 
You need to output 2.
解题思路:

该题目的意思是,给定两个数组,一个数组代表饼干的数量,另一个数组代表每个小孩的需求量,最终求解的是最多能够满足多少个小孩。我们可以先对两个数组进行排序,从最大到小开始查看,如果饼干可以满足小孩,则执行--进行下一组匹配,如果不满足,则继续查看下一个小孩。直到遍历完成为止。

代码如下:

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) 
    {
        sort(g.begin(),g.end());
        sort(s.begin(),s.end());
        int ret=0;
        int x=g.size()-1;
        int y=s.size()-1;
        while(x>=0&&y>=0)
        {
            if(g[x]>s[y])
            {
                x--;
            }
            else
            {
                if(g[x] <= s[y]) 
                {
                    x--;
                    y--;
                    ret++;
                }
            }
        }
        return ret;
        
    }
};
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 1:

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

Note:

  1. The number of tasks is in the range [1, 10000].
  2. The integer n is in the range [0, 100].
题目解析:

此题目的意思是给定一些任务,相同的任务必须间隔n才能执行,比如example1,在开始执行A之后,必须间隔两个时间段才能执行A。刚开始的时候想到的是,先计算每一个任务出现的次数,然后先分配出现次数最多的任务,如果出现最多的任务A,出现的次数为count次,那么执行完任务A至少需要(count-1)*(n+1)+1个时间段。如果还有其他的跟任务A一样多次的任务,则时间段++(可以手动画一下)将每一个都放在A任务之后,最后一个需要+1。然后比较给定的任务量和需要的时间段,取最大值即可。代码如下:

class Solution {
public:
    int leastInterval(vector<char>& tasks, int n) 
    {
        unordered_map<char,int> hash;
        int count=0;
        int ret=0;
        for(auto task:tasks)
        {
            hash[task]++;
            if(hash[task]>count)
            {
                count=hash[task];
            }
        }
        ret=(count-1)*(n+1);
        for(auto it:hash)
        {
            if(it.second==count)
            {
                ret++;
            }
        }
        return max((int)tasks.size(),ret);
        
    }
};

55. Jump Game

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Determine if you are able to reach the last index.

For example:
A = [2,3,1,1,4], return true.

A = [3,2,1,0,4], return false.

解题思路:

数组A的元素代表当前能够走的最大步数,该题目的意思是判断是否能够到达最后一个元素。刚开始的思路没整明白如何用贪心来做,我们可以这样来想:没走一个元素,记录一下当前可以到达的最远距离,如果最远距离大于等于终点,则停止。如果上一步到达的最远距离,小于当前的距离,说明当前的位置是到达不了的,则退出。代码如下:

class Solution {
public:
    bool canJump(vector<int>& nums) 
    {
        int maxId=0;
        int n=nums.size();
        for(int i=0;i<n;i++)
        {
            if(maxId<i||maxId>=n-1)
            {
                break;
            }
            if(maxId<=i+nums[i])
            {
                maxId=i+nums[i];
            }
        }
        if(maxId>=n-1)
        {
            return true;
        }
        return false;
    }
};

376. Wiggle Subsequence

A sequence of numbers is called a wiggle sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a wiggle sequence.

For example, [1,7,4,9,2,5] is a wiggle sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast, [1,4,7,2,5] and [1,7,4,5,5] are not wiggle sequences, the first because its first two differences are positive and the second because its last difference is zero.

Given a sequence of integers, return the length of the longest subsequence that is a wiggle sequence. A subsequence is obtained by deleting some number of elements (eventually, also zero) from the original sequence, leaving the remaining elements in their original order.

Examples:

Input: [1,7,4,9,2,5]
Output: 6
The entire sequence is a wiggle sequence.

Input: [1,17,5,10,13,15,10,5,16,8]
Output: 7
There are several subsequences that achieve this length. One is [1,17,10,13,10,16,8].

Input: [1,2,3,4,5,6,7,8,9]
Output: 2

class Solution {
public:
    //dp
    int wiggleMaxLength(vector<int>& nums) 
    {
        int n=nums.size();
        if(n==0)
        {
            return 0;
        }
        vector<int> up(n,1);
        vector<int> down(n,1);
        for(int i=1;i<n;i++)
        {
            if(nums[i]>nums[i-1])
            {
                up[i]=max(up[i],down[i-1]+1);
                down[i]=down[i-1];
            }
            if(nums[i]<nums[i-1])
            {
                down[i]=max(down[i],up[i-1]+1);
                up[i]=up[i-1];
                
            }
            if(nums[i]==nums[i-1])
            {
                down[i]=down[i-1];
                up[i]=up[i-1];
            }
        }
        return max(up[n-1],down[n-1]);
        
    }
};

class Solution {
public:
    //greedy
    int wiggleMaxLength(vector<int>& nums) 
    {
        int n=nums.size();
        if(n==0)
        {
            return 0;
        }
        int up=1;
        int down=1;
        for(int i=1;i<n;i++)
        {
            if(nums[i]>nums[i-1])
            {
                up=down+1;
            }
            if(nums[i]<nums[i-1])
            {
                down=up+1;
            }
        }
        return max(up,down);
    }
};

134. Gas Station

There are N gas stations along a circular route, where the amount of gas at station i is gas[i].

You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.

Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.

Note:
The solution is guaranteed to be unique.

我们首先要知道能走完整个环的前提是gas的总量要大于cost的总量,这样才会有起点的存在。假设开始设置起点start = 0, 并从这里出发,如果当前的gas值大于cost值,就可以继续前进,此时到下一个站点,剩余的gas加上当前的gas再减去cost,看是否大于0,若大于0,则继续前进。当到达某一站点时,若这个值小于0了,则说明从起点到这个点中间的任何一个点都不能作为起点,则把起点设为下一个点,继续遍历。当遍历完整个环时,当前保存的起点即为所求

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) 
    {
        int total=0;
        int sum=0;
        int start=0;
        for(int i=0;i<gas.size();i++)
        {
            total=total+gas[i]-cost[i];
            sum=sum+gas[i]-cost[i];
            if(sum<0)
            {
                start=i+1;
                sum=0;
            }
            
        }
        if(total<0)
        {
            return -1;
        }
        else
        {
            return start;
        }
        
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值