45、跳跃游戏 II
给你一个非负整数数组 nums ,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
思路:只要考虑每一跳所能达到的最远位置就行了,也就是每次都选择最远可达的点,reach是当前需要进行跳跃的右界限(在界限范围内只算一步【没有更新界限的情况下】),nextReach是下一次跳跃的右界限,nextReach的值一直动态更新,以保证每次跳跃都是最远的
i表示遍历数组的时候,在界限reach内来查找下一个界限nextreach的范围【即:查找界限内最大的值】当i==reach,表示在界限内已经找到了最大的值了,这时候step++,且更新界限的新的范围【reach=nextreach】。如果判断下一界限的范围能够覆盖数组最后一个索引,这时候就return step+1.
class Solution {
public int jump(int[] nums) {
//只要考虑每一跳所能达到的最远位置就行了,也就是每次都选择最远可达的点,
//reach是当前需要进行跳跃的右界限,nextReach是下一次跳跃的右界限,
//nextReach的值一直动态更新,以保证每次跳跃都是最远的
if(nums.length == 1) return 0;
int reach = 0;
int nextreach = nums[0];
int step = 0;
for(int i = 0;i<nums.length;i++){
nextreach = Math.max(i+nums[i],nextreach);
if(nextreach >= nums.length-1) return (step+1);
if(i == reach){
step++;
reach = nextreach;
}
}
return step;
}
}
728、自除数(每日一题,不是贪心算法)
重新复习获取一个数(不知道他是几位数)的每一个个数的值
class Solution {
public List<Integer> selfDividingNumbers(int left, int right) {
List<Integer>list=new ArrayList<>();
for(int i=left;i<=right;i++){
if(isValid(i)){
list.add(i);
}
}
return list;
}
public boolean isValid(int i){
int temp=i;
while(temp>0){
int digit=temp%10;//防止digit为0
if(digit==0||i%digit!=0){//因为要判断【i%i的每个个数】是否为0,所以i不能变,而每次i都要除10才能算出个位数/十位数/百位数,所以这时候要用临时变量来替代i。
return false;
}
temp=temp/10;
}
return true;
}
}
1005、K 次取反后最大化的数组和
给你一个整数数组 nums
和一个整数 k
,按以下方法修改该数组:
- 选择某个下标
i
并将nums[i]
替换为-nums[i]
。
重复这个过程恰好 k
次。可以多次选择同一个下标 i
。
以这种方式修改数组后,返回数组 可能的最大和 。
class Solution {
public int largestSumAfterKNegations(int[] nums, int k) {
Arrays.sort(nums);
int sum=0;
int index=-1;//查找数组中是否有0的索引
//为了最大,把数组中的负数变成正数
for(int i=0;i<nums.length;i++){
if(nums[i]<0&&k>0){
nums[i]=-nums[i];
k--;//将 nums[i] 替换为 -nums[i] ,要执行k次
}
if(nums[i]==0){
index=i;
}
}
//判断数组中是否有0的存在
if(index>=0){
while(k>0){
nums[index]=-nums[index];
k--;
}
}
//经过上述操作后只剩下正数了,那么重新排序
Arrays.sort(nums);
//判断把负数和0都替换后,还要执行多少次
for(int i=0;i<k;i++){
nums[0]=-nums[0];
}
for(int num:nums){
sum+=num;
}
return sum;
}
}