数据结构与算法——贪心算法

1.分发饼干
1.1 题目描述

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

题目来源于力扣455

1.2 解题思路

在这里插入图片描述
在这里插入图片描述

1.3 C++实现
class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        sort(g.begin(),g.end());
        sort(s.begin(),s.end());

        int child=0;
        int cookie=0;
        while((child<g.size())&&(cookie<s.size())){
            if(g[child]<=s[cookie]){
                child++;
            }
            cookie++;
        }
        return child;
    }
};
2.摆动序列
2.1 题目描述

如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。

例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的。相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。

给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。

2.2 解题思路

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

2.3 C++实现
class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if(nums.size()<2){
            return nums.size();
        }

        static const int BEGIN=0;
        static const int UP=1;
        static const int DOWN=2;
        int STATE=BEGIN;
        int max_length=1;
        for(int i=1;i<nums.size();i++){
            switch(STATE){
                case BEGIN:
                    if(nums[i]>nums[i-1]){
                        STATE=UP;
                        max_length++;
                    }
                    else if(nums[i]<nums[i-1]){
                        STATE=DOWN;
                        max_length++;
                    }
                    break;
                case UP:
                    if(nums[i]<nums[i-1]){
                        STATE=DOWN;
                        max_length++;
                    }
                    break;
                case DOWN:
                    if(nums[i]>nums[i-1]){
                        STATE=UP;
                        max_length++;
                    }
                    break;
            }            
        }
        return max_length;
    }
};
3.移掉K位数字
3.1 题目描述

给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。

num 的长度小于 10002 且 ≥ k。
num 不会包含任何前导零。

3.2 解题思路

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3 C++实现
class Solution {
public:
    string removeKdigits(string num, int k) {
        vector<int> S;
        string result="";
        for(int i=0;i<num.length();i++){
            int number=num[i]-'0';
            while(S.size()!=0&&S[S.size()-1]>number&&k>0){
                S.pop_back();
                k--;
            }
            if(S.size()!=0||number!=0){
                S.push_back(number);
            }
        }

        while(S.size()!=0&&k>0){
            S.pop_back();
            k--;
        }
        for(int i=0;i<S.size();i++){
            result.append(1,'0'+S[i]);
        }
        if(result==""){
            return "0";
        }
        return result;

    }
};
4.跳跃游戏
4.1 题目描述

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标。

4.2 解题思路

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4.3 C++实现
class Solution {
public:
    bool canJump(vector<int>& nums) {
        vector<int> index;
        for(int i=0;i<nums.size();i++){
            index.push_back(i+nums[i]);
        }

        int max_index=index[0];
        int jump=0;
        while(jump<index.size()&&jump<=max_index){
            if(max_index<index[jump]){
                max_index=index[jump];
            }
            jump++;
        }
        if(jump==nums.size()){
            return true;
        }
        return false;
    }
};
5.跳跃游戏 II
5.1 题目描述

给定一个非负整数数组,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

你的目标是使用最少的跳跃次数到达数组的最后一个位置。

5.2 解题思路

在这里插入图片描述

5.3 C++实现
class Solution {
public:
    int jump(vector<int>& nums) {
        if(nums.size()<2){
            return 0;
        }

        int current_max_index=nums[0];
        int pre_max_max_index=nums[0];
        int jump=1;
        for(int i=0;i<nums.size();i++){
            if(i>current_max_index){
                jump++;
                current_max_index=pre_max_max_index;
            }
            if(pre_max_max_index<nums[i]+i){
                pre_max_max_index=nums[i]+i;
            }
        }
        return jump;
    }
};
6.用最少数量的箭引爆气球
6.1 题目描述

在二维空间中有许多球形的气球。对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标。由于它是水平的,所以纵坐标并不重要,因此只要知道开始和结束的横坐标就足够了。开始坐标总是小于结束坐标。

一支弓箭可以沿着 x 轴从不同点完全垂直地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被引爆。可以射出的弓箭的数量没有限制。 弓箭一旦被射出之后,可以无限地前进。我们想找到使得所有气球全部被引爆,所需的弓箭的最小数量。

给你一个数组 points ,其中 points [i] = [xstart,xend] ,返回引爆所有气球所必须射出的最小弓箭数。

6.2 解题思路

在这里插入图片描述
在这里插入图片描述

6.3 C++实现
class Solution {
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        if(points.size()==0){
            return 0;
        }
        sort(points.begin(),points.end());

        int shoot_num=1;
        int shoot_begin=points[0][0];
        int shoot_end=points[0][1];
        for(int i=1;i<points.size();i++){
            if(shoot_end>=points[i][0]){
                shoot_begin=points[i][0];
                if(shoot_end>points[i][1]){
                    shoot_end=points[i][1];
                }
            }
            else{
                shoot_num++;
                shoot_begin=points[i][0];
                shoot_end=points[i][1];
            }
        }
        return shoot_num;
    }
};
7.最优加油方法
7.1 题目描述

在这里插入图片描述

7.2 解题思路

在这里插入图片描述在这里插入图片描述

7.3 C++实现
#include <iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;

bool cmp(pair<int, int>& a, pair<int, int>& b) {
    return a.first > b.first;
}

int get_min_stop(int L, int P, vector < pair<int, int>>& stop)
{
    priority_queue<int> Q;
    int result = 0;
    stop.push_back(make_pair(0, 0));
    sort(stop.begin(), stop.end(), cmp);
    for (int i = 0; i < stop.size(); i++) {
        int dis = L - stop[i].first;
        while (dis > P && !Q.empty()) {
            P = P + Q.top();
            Q.pop();
            result++;
        }
        if (Q.empty() && dis > P) {
            return -1;
        }
        P = P - dis;
        L = stop[i].first;
        Q.push(stop[i].second);
    }
    return result;
}
int main()
{
    vector<pair<int,int>> stop;
    int L, P;
    L = 25;
    P = 10;
    stop.push_back(make_pair(4, 4));
    stop.push_back(make_pair(5, 2));
    stop.push_back(make_pair(11, 5));
    stop.push_back(make_pair(15, 10));
    cout << "加油次数:" << get_min_stop(L, P, stop) << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值