持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情
本文包括下面几题:
- 跳跃游戏II,数组中每个位置代表可跳跃的最大长度,要求找到最少跳到最后一个位置的次数。
- 给定一个数组
nums和一个整数k,选择某个下标i并将nums[i]替换为-nums[i],整个过程恰好k次。
解题思路
LeetCode 45 跳跃游戏II
本题和之前跳跃游戏的思路一致,都是使用最大跳跃范围来解答,但什么时候步数增加是本题需要考虑的问题。首先考虑每步的最大范围,需要注意的是,每步的最大范围并不是我们已经走到的位置,只是可到达的位置,那中间应该走几步我们是不知道的。
想象一下,如果数组为[2,3,1,1,4],那第一步的最大范围为走到数组中第一个1,那究竟是先走到3再走到1是不得而知的,但可以确定的是,如果我们顺序遍历到了第一个1,那第一步必然是走了的,此时就可以步数加一,既然第一步走完了,那么我们可以根据更新最大范围,找到我们肯定走到的第二步。可得代码如下:
public int jump(int[] nums) {
if(nums.length==1) return 0;
int count = 0;
int maxRange = 0;
int curRange = 0;
for(int i=0;i<nums.length-1;i++){
maxRange = Math.max(maxRange, i+nums[i]);
if(i==curRange){
curRange = maxRange;
count++;
}
if(curRange>=nums.length-1) return count;
}
return count;
}
叙述的较为抽象,可结合代码来看。
LeetCode 1005 k次取反后最大化数组和
本题的思路很简单,我们只需要将数组按照绝对值从大到小排序,每次将大的负数反转,如果最终k还大于0,那只需要对最小的一个数进行来回翻转即可,最终就可以得到结果。
根据上述思路可得代码如下:
public int largestSumAfterKNegations(int[] nums, int k) {
int res = 0;
nums = IntStream.of(nums)
.boxed()
.sorted((o1, o2) -> Math.abs(o2) - Math.abs(o1))
.mapToInt(Integer::intValue).toArray();
for(int i=0;i<nums.length;i++){
if(nums[i]<0&&k>0){
nums[i] = -nums[i];
k--;
}
}
if(k!=0){
nums[nums.length-1] = k%2==1?-nums[nums.length-1]:nums[nums.length-1];
}
for (int num : nums) {
res+=num;
}
return res;
}