每日一题(day4)

前言

💫你好,我是辰chen,一个正在考研途中的 s o p h o m o r e sophomore sophomore d o g dog dog😖
💫目前每日一题主要来自于 leetcode,当然也可能来自洛谷或其他刷题平台,每日一题专栏地址:每日一题
💫欢迎大家的关注,我的博客主要关注于考研408以及AIoT的内容

🌟 每日一题我会给出两种代码, C C C版以及 P y t h o n Python Python版,刷题的目的是为了考研的算法题以及机试(或手写代码)
🌟这也是为什么不用 C + + C++ C++ 而用 C C C P y t h o n Python Python版代码是为了提高语言熟练度(以后开发大概率用的是 P y t h o n Python Python
🌟 坚持打卡!踏踏实实走好每一步

以下的几个专栏是本人比较满意的专栏(大部分专栏仍在持续更新),欢迎大家的关注:

💥ACM-ICPC算法汇总【基础篇】
💥ACM-ICPC算法汇总【提高篇】
💥AIoT(人工智能+物联网)
💥考研
💥CSP认证考试历年题解

👊每日一句一份耕耘,一份收获。

大家做完可以在评论区打卡留言✒️,形成良好的学习氛围,一起进步!

LeetCode 55. 跳跃游戏

题目描述:

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

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

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

示例 1:

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

示例 2:

输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

提示:

1 < = n u m s . l e n g t h < = 3 ∗ 1 0 4 1 <= nums.length <= 3 * 10^4 1<=nums.length<=3104
0 < = n u m s [ i ] < = 1 0 5 0 <= nums[i] <= 10^5 0<=nums[i]<=105

思路: 贪心,每次都更新最远可以到达的距离 m a x l e n maxlen maxlen,我们可以到达的点的坐标就是 [ i + 1 , m a x l e n ] [i+1, maxlen] [i+1,maxlen],故如果我们的最终点坐标小于等于最远距离,即 numSize-1 <= maxlen,就证明可以到达,反之不可以到达

C版AC代码:

bool canJump(int* nums, int numsSize){
    int maxlen = 0;
    for (int i = 0; i < numsSize; i ++ ){
        if (i <= maxlen){
            maxlen = fmax(maxlen, i + nums[i]);
        }
        if (maxlen >= numsSize - 1){
            return true;
        }
    }
    return false;
}

Python版AC代码:

class Solution:
    def canJump(self, nums: List[int]) -> bool:
        n, maxlen = len(nums), 0
        for i in range (n):
            if (i <= maxlen):
                maxlen = max(maxlen, nums[i] + i)
            if maxlen >= n - 1:
                return True
        return False

LeetCode 45. 跳跃游戏 II

题目描述:

给你一个非负整数数组 n u m s nums nums ,你最初位于数组的第一个位置。

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

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

假设你总是可以到达数组的最后一个位置。

示例 1:

输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
     从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

示例 2:

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

提示:

1 < = n u m s . l e n g t h < = 1 0 4 1 <= nums.length <= 10^4 1<=nums.length<=104
0 < = n u m s [ i ] < = 1000 0 <= nums[i] <= 1000 0<=nums[i]<=1000

思路: 贪心,因为我们要求到达最终点的次数最少,故我们每次选择可以跳跃的最远的点,举个栗子,比如我们此时在 i i i 点, n u m s [ i ] = 2 nums[i]=2 nums[i]=2,即从 i i i 点可以跳跃到 i + 1 i+1 i+1 以及 i + 2 i+2 i+2,那么我们选择最优点即看 ( i + 1 ) + n u m s [ i + 1 ] (i+1)+nums[i+1] (i+1)+nums[i+1] ( i + 2 ) + n u m s [ i + 2 ] (i+2)+nums[i+2] (i+2)+nums[i+2] 哪一个更大,选择一个更大的点跳跃到该点上; m a x l e n maxlen maxlen 代表的可以跳跃到的最远距离, s t e p step step 即为跳跃的次数, e n d end end 即跳跃可以到达的区间右端点,比如上述栗子中 n u m s [ i ] = 2 nums[i]=2 nums[i]=2,即 e n d = n u m s [ i ] + 2 end = nums[i]+2 end=nums[i]+2;这里还有一个点,就是我们在进行 f o r for for 循环进行遍历的时候,不可以遍历到最后一个点,只能遍历到倒数第二个点,这是因为在遍历到倒数第二个点的时候有两种情况:遇到了 e n d end end,那么只需要跳跃一次即可;没有遇到 e n d end end,此时 end >= len(nums) - 1,即上一次跳跃的范围已经覆盖到了最远的一个点,此时就不需要进行跳跃;如果遍历到最后一个点,那么当 end == len(nums) - 1 的时候就还会进行一次多余的跳跃,当然你可以用 i f if if 特判掉这种情况,下面同样给出特判后的 C C C A C AC AC代码

C版AC代码:

int jump(int* nums, int numsSize){
    int step = 0, end = 0, maxlen = 0;
    for (int i = 0; i < numsSize - 1; i ++ ){
        maxlen = fmax(maxlen, nums[i] + i);
        if (i == end){
            step ++;
            end = maxlen;
        }
    }
    return step;
}

C版AC代码(特判):

int jump(int* nums, int numsSize){
    int step = 0, end = 0, maxlen = 0;
    for (int i = 0; i < numsSize; i ++ ){
        maxlen = fmax(maxlen, nums[i] + i);
        if (i == end && end != numsSize - 1){
            step ++;
            end = maxlen;
        }
    }
    return step;
}

Python版AC代码:

class Solution:
    def jump(self, nums: List[int]) -> int:
        maxlen, end, step = 0, 0, 0
        n = len(nums)
        for i in range(n - 1):
            maxlen = max(maxlen, nums[i] + i)
            if i == end:
                step += 1
                end = maxlen
        return step

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辰chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值