算法沉淀——贪心算法五

01.跳跃游戏 II02.跳跃游戏03.加油站04.单调递增的数字

01.跳跃游戏 II

题目链接:https://leetcode.cn/problems/jump-game-ii/

给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:

0 <= j <= nums[i]i + j < n

返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。

示例 1:

输入: nums = [2,3,1,1,4]

输出: 2

解释: 跳到最后一个位置的最小跳跃数是 2。

从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

示例 2:

输入: nums = [2,3,0,1,4]

输出: 2

提示:

1 <= nums.length <= 1040 <= nums[i] <= 1000题目保证可以到达 nums[n-1]

思路

这里我们可以利用层序遍历的思想进行数组遍历,从第一步开始,计算每一步能跨出的范围内最大的那个数字的步数,这样我们就可以找到需要使用的最小的跳跃步数。

代码

class Solution {

public:

int jump(vector& nums) {

int left=0,right=0,maxPos=0,count=0,n=nums.size();

while(left<=right){

if(maxPos>=n-1) return count;

for(int i=left;i<=right;i++) maxPos=max(maxPos,nums[i]+i);

left=right+1;

right=maxPos;

count++;

}

return -1;

}

};

02.跳跃游戏

题目链接:https://leetcode.cn/problems/jump-game/

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。

示例 1:

输入:nums = [2,3,1,1,4]

输出:true

解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

示例 2:

输入:nums = [3,2,1,0,4]

输出:false

解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

提示:

1 <= nums.length <= 1040 <= nums[i] <= 105

思路

这道题可以借用上面的思想,只需修改返回值即可。

代码

class Solution {

public:

bool canJump(vector& nums) {

int left=0,right=0,maxPos=0,count=0,n=nums.size();

while(left<=right){

if(maxPos>=n-1) return true;

for(int i=left;i<=right;i++) maxPos=max(maxPos,nums[i]+i);

left=right+1;

right=maxPos;

count++;

}

return false;

}

};

03.加油站

题目链接:https://leetcode.cn/problems/gas-station/

在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。

示例 1:

输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2]

输出: 3

解释:

从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油

开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油

开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油

开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油

开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油

开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。

因此,3 可为起始索引。

示例 2:

输入: gas = [2,3,4], cost = [3,4,3]

输出: -1

解释:

你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。

我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油

开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油

开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油

你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。

因此,无论怎样,你都不可能绕环路行驶一周。

提示:

gas.length == ncost.length == n1 <= n <= 1050 <= gas[i], cost[i] <= 104

思路

枚举所有起点,模拟加油的流程,但在这里做一个优化,就是贪心思想,我们在枚举每一个点时,若该点不成功,就直接跳过中间所有点,这样我们可以做很大的优化。

代码

class Solution {

public:

int canCompleteCircuit(vector& gas, vector& cost) {

int n=gas.size();

for(int i=0;i

int rest = 0, step = 0;

while(step

int index=(i+step)%n;

rest+=gas[index]-cost[index];

if(rest<0) break;

step++;

}

if(rest>=0) return i;

i+=step;

}

return -1;

}

};

04.单调递增的数字

题目链接:https://leetcode.cn/problems/monotone-increasing-digits/

当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。

给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。

示例 1:

输入: n = 10

输出: 9

示例 2:

输入: n = 1234

输出: 1234

示例 3:

输入: n = 332

输出: 299

提示:

0 <= n <= 109

思路

为了方便处理数字,我们可以先将整数转换成字符串,然后从左往右扫描,找到第一个递减的位置,然后从这个位置往前推,推到相同数字的最前端,该位置-1,后面所有数都改成9,这样就得到最终结果

代码

class Solution {

public:

int monotoneIncreasingDigits(int n) {

string s=to_string(n);

int i=0,m=s.size();

while(i+1

if(i+1==m) return n;

while(i-1>=0&&s[i]==s[i-1]) i--;

s[i]--;

for(int j=i+1;j

return stoi(s);

}

};

好文阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。