贪心算法(leetcode)

1 分糖果 455

用最小的糖果大小满足需求最小的孩子

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        sort(g.begin(), g.end());
        sort(s.begin(), s.end());
        int i = 0;
        int j = 0;
        int count = 0;
        while(i<g.size() && j < s.size()){
            if(g[i]>s[j]){
                j += 1;
            }else{
                count += 1;
                j += 1;
                i += 1;
            }
        }
        return count;
    }
};

2 摇摆序列  376

遍历一次,保存一个状态,如果状态为上升,变为下降,则长度+1,下降变上升+1

class Solution:
    def wiggleMaxLength(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) < 2:
            return len(nums)
        up = 1
        begin = 0
        down = 2
        length = 1
        state = begin;
        for i in range(1, len(nums)):
            if state == begin:
                if nums[i] > nums[i-1]:
                    state = up
                    length += 1
                elif nums[i] < nums[i-1]:
                    state = down
                    length += 1
                else:
                    state = begin
            elif state == up:
                if nums[i] >= nums[i-1]:
                    state = up
                elif nums[i] < nums[i-1]:
                    state = down
                    length += 1
            elif state == down:
                if nums[i] > nums[i-1]:
                    state = up
                    length += 1
                else:
                    state = down
        return length

3 移除K个数字 402

问题:求移除K个数字后能够获得的最小的可能的新数字

思路:

例如 1432219  从高位开始遍历 如果高位值比低位值大的话说明需要去掉 

遍历字符串,用一个栈来保存需要保留的元素,如果栈顶元素>新元素  需要pop   还有2个特殊情况,如果栈为空,且新元素为0则不要他了,第二个如果 遍历完k仍然大于0  比如12345  则把后面的元素去掉就行了

class Solution:
    def removeKdigits(self, num, k):
        """
        :type num: str
        :type k: int
        :rtype: str
        """
        stack = []
        for i in range(len(num)):
            while stack and int(stack[-1]) > int(num[i]) and k > 0:
                stack.pop()
                k -= 1
            if num[i] != '0' or len(stack)!= 0:
                stack.append(num[i])
        while k > 0 and stack:
            stack.pop()
            k -= 1
        return ''.join(stack) if stack else '0'

4 跳跃游戏 55

题目:一个数组a中每一个元素保存了可以从当前位置向后跳a[i] 步  ,能否从0跳到最后

max_index为能到达的最远位置,jump为当前所处位置,如果jump<max_index 就一直向前走,过程中更新max_index如果jump走到了最后 说明可以

class Solution {
public:
    bool canJump(vector<int>& nums) {
        vector<int> index;
        for(int i=0;i<nums.size();i++){
            index.push_back(nums[i]+i);
        }
        int max_index = nums[0];
        int jump = 0;
        while(jump < nums.size() && jump <= max_index){
            if (max_index < index[jump]){
                max_index = index[jump];
            }
            jump ++;
        }
        if(jump == nums.size()){
            return true;
        }
        return false;
    }
};

5 跳跃游戏2 45  

题目:确定可以跳到最后,最少需要几次跳跃

设置cur_max_index 和 pre_max_index 一直往前走 维护pre_max_index 如果当前位置<cur_max_index的话 就必须要跳了,选能跳的最远的一个跳 ,更新cur_max_index = pre_max_index jump++

class Solution {
public:
    int jump(vector<int>& nums) {
        if(nums.size() < 2){
            return 0;
        }
        int cur_max_index = nums[0];//当前可达到的最远位置
        int every_max_index = nums[0]; //遍历各个位置过程中,能达到的最远位置
        int jump = 1;
        for(int i = 0;i<nums.size();i++){
            if(i>cur_max_index){
                jump ++;//如果不能前进了,就必须要跳了
                cur_max_index = every_max_index;
            }
            if(every_max_index<nums[i] + i){
                every_max_index = nums[i] + i;
            }
        }
        return jump;
    }
};

6 射击气球 452

题目:给定x轴上,给定几个气球位置, 最少需要几个弓箭手把气球射爆

思路:把坐标按左值进行排序,维护一个射击区间,遍历过程中,如果有交集则 更新射击区间,不行就加弓箭手

bool cmp(const pair<int, int> &a, const pair<int, int> &b){
        return a.first < b.first;
    }
class Solution {
public:
    //设定一个设计区间,遍历气球数组 ,更新射击区间,如果不在范围内就 增加射击员
    int findMinArrowShots(vector<pair<int, int>>& points) {
        if(points.size() == 0){
            return 0;
        }
        sort(points.begin(), points.end(), cmp);
        int shot_begin = points[0].first;
        int shot_end = points[0].second;
        int shooter = 1;
        for(int i =1; i< points.size();i++){
            if(points[i].first <= shot_end){
                shot_begin = points[i].first;
                if(points[i].second <= shot_end){
                    shot_end = points[i].second;
                }
            }
            else{
                shooter ++;
                shot_begin = points[i].first;
                shot_end = points[i].second;
            }
        }
        return shooter;
    }
};

7 最低加油次数  871

思路:

把target加入到加油站中,遍历加油站,每次判断能不能到达下一个加油站,一直维持加油数组,如果不能到达下一个加油站,就选择其中一个最多油的地方加油

class Solution:
    def minRefuelStops(self, target, startFuel, stations):
        """
        :type target: int
        :type startFuel: int
        :type stations: List[List[int]]
        :rtype: int
        """
        if len(stations) == 0:
            return 0 if startFuel >= target else -1
        pre_station = 0
        qiyou = []
        stations.append([target, 0])
        ret = 0
        cur_qiyou = startFuel
        for i in range(len(stations)):
            dis = stations[i][0] - pre_station
            while(qiyou and cur_qiyou < dis):
                cur_qiyou += max(qiyou)
                qiyou.remove(max(qiyou))
                ret += 1
            if(len(qiyou) == 0 and cur_qiyou < dis):
                return -1
            cur_qiyou -= dis
            pre_station = stations[i][0]
            qiyou.append(stations[i][1])
        return ret

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值