贪心算法-nowcoder

1.我理解的贪心算法就是,类似于从根节点去向下求一个最优解,你不知道每层有几个节点,也不知道是否能达到自己想到的地方。

2.当无法更新最优解时,又没有到达自己的目的,则停止;或者达到自己的目的,停止。

3.当前最优解优于上一个最优解时,最优解更新

4.不需要去记录所有的最优解。一般复杂度低。

该算法存在的问题
1.不能保证求得的最后解是最佳的
2.不能用来求最大值或最小值的问题
3.只能求满足某些约束条件的可行解的范围

描述

一群孩子做游戏,现在请你根据游戏得分来发糖果,要求如下:

1. 每个孩子不管得分多少,起码分到一个糖果。

2. 任意两个相邻的孩子之间,得分较多的孩子必须拿多一些糖果。(若相同则无此限制)

给定一个数组 arrarr 代表得分数组,请返回最少需要多少糖果。

要求: 时间复杂度为 O(n) 空间复杂度为 O(n)

数据范围: 1≤n≤100000 ,1≤ai​≤1000

//int为全为1的vector sample
//你可以从左到右遍历,从第二位开始判断(第一个不需要比较)
//当a[n+1]>a[n]但sample[n+1]<=sample[n],sample[n+1]=sample[n]+1
//然后从右到左再次遍历,从倒数第二位开始判断。

class Solution {
public:
    /**
     * pick candy
     * @param arr int整型vector the array
     * @return int整型
     */
    int candy(vector<int>& arr) {
        // write code here
        int len= arr.size();
        if(len<=1){
            return len;
        }
        vector<int> sample(len,1);
        for(int i=0;i<len-1;i++){
            if(arr[i]<arr[i+1]&&sample[i]>=sample[i+1])
                sample[i+1]=sample[i]+1;
        }
        for(int i=len-2;i>=0;i--){
            if(arr[i]>arr[i+1]&&sample[i]<=sample[i+1])
                sample[i]=sample[i+1]+1;
        }
        int res=0;
        for(int i=0;i<len;i++){
            res=res+sample[i];
        }
        return res;
    }
};

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

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

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

示例 1:

输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

//你可以从0开始向下探寻
//停止条件为当前最大长度maxl小于当前格子位置
//且当前格子无法进行到下一个格子
//初始长度为0

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int len = nums.size();
        if(len<=1)
            return true;
        int max_l=0;
        for(int i=0;i<=max_l;i++){
            max_l=max(i+nums[i],max_l);
            if(max_l>=len-1)
                return true;
        }
        return false;
    }
};
有 n 个活动即将举办,每个活动都有开始时间与活动的结束时间,
第 i 个活动的开始时间是 starti ,
第 i 个活动的结束时间是 endi ,
举办某个活动就需要为该活动准备一个活动主持人。

一位活动主持人在同一时间只能参与一个活动。并且活动主持人需要全程参与活动,
换句话说,一个主持人参与了第 i 个活动,
那么该主持人在 (starti,endi) 这个时间段不能参与其他任何活动。
求为了成功举办这 n 个活动,最少需要多少名主持人。

数据范围: 1≤n≤10^5,−2^32≤start_i≤end_i≤2^31−1
复杂度要求:时间复杂度 O(nlogn) ,空间复杂度 O(n)
面对这个问题,我一开始考虑的就是单纯的从头到尾的去遍历,一个一个vector去判断,
是否应当出,此刻有几个活动。
其实我们只需要考虑,在下一个开始的时候,有几个还没有结束就可以了。
把vector<vector<>>二维数组,转化为两个一维数组,start、end。
如果start[i]>=end[j],j++,
如果start[i]<end[j],res++,

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算成功举办活动需要多少名主持人
     * @param n int整型 有n个活动
     * @param startEnd int整型vector<vector<>> startEnd[i][0]用于表示第i个活动的开始时间,startEnd[i][1]表示第i个活动的结束时间
     * @return int整型
     */
    int minmumNumberOfHost(int n, vector<vector<int> >& startEnd) {
        // write code here
        if(n<=1)
            return n;
        int res = 0;
        int tmp = 0;
        vector<int> start(n,0),end(n,0);
        for(int i=0;i<n;i++){
            start[i]=startEnd[i][0];
            end[i]=startEnd[i][1];
        }
        sort(start.begin(),start.end());
        sort(end.begin(),end.end());
        for(int i=0;i<n;i++){
            if(start[i]>=end[tmp])
                tmp++;
            else
                res++;
        }
        return res;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值