前言
💫你好,我是辰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<=3∗104
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