持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情
本文包含以下几题:
- 给定一个非负数组
nums,最初位于数组的第一个下标,数组中每个元素代表在此位置可跳跃的最大长度,判断是否可以到达最后一个下标。 - 计算快乐数。数字各位平方之和递归最终为1即为快乐数。
解题思路
LeetCode 55 跳跃游戏
本题可用贪心法解决,思路有两种:
在跳跃时,不可避免的我们会想下一步到底跳几步,下下步又该如何,这样思考下去分分钟放弃本题。实际上,本题只需要思考当前下标可到达的最大范围即可,只要最终可到达的位置大于等于数组最后一个位置即可,判断每个位置可到达的最大位置为i + nums[i],根据该思路可得代码如下:
public boolean canJump(int[] nums) {
int coverRange = 0;
for(int i=0;i<=coverRange;i++){
coverRange = Math.max(coverRange, i+nums[i]);
if(coverRange>= nums.length-1) return true;
}
return false;
}
思路二:既然我们可用从前往后判断是否可到达最后一个位置,那是否可根据末尾位置是否可到达首元素位置来判断是否满足条件。我们只需要不断更新终点位置即可,更新终点位置的方法和上面思路类似,也是通过判断i+nums[i]是否可到达数组末尾判断。可得代码如下:
public boolean canJump2(int[] nums) {
int end = nums.length-1;
for(int i=end;i>=0;i--){
if((i+nums[i])>=end) end = i;
}
return end==0;
}
LeetCode 202 快乐数
本题的关键就是找到什么情况下不是快乐数,一般规律很难找,我们只能将希望放在另一个条件上了,另一个结束条件是无限循环,那本题就转为了如何判定是无限循环了。
无限循环的判定很简单,我们只需要使用set来保存每次的结果,最终如果存在重复的那就是无限循环了,还有一个思路是快慢指针,我们只需要让一个数字先计算两次,另一个数字计算一次,这样不断循环下来最终必然会到达相同的结果,无论是不是快乐数。
可得代码如下:
双指针法:
public boolean isHappy3(int n) {
int fast = n,slow = n;
do{
fast = getNext(fast);
fast = getNext(fast);
slow = getNext(slow);
}while(fast!=slow);
return slow == 1;
}
public int getNext(int n){
int value = 0;
while(n!=0){
value += Math.pow(n%10,2);
n = n/10;
}
return value;
}
set去重:
public boolean isHappy3(int n) {
HashSet<Integer> set = new HashSet<>();
set.add(n);
while(n!=1){
n = getNext(n);
if(set.contains(n)){
return false;
}else {
set.add(n);
}
}
return true;
}
实际上,本题的关键是找到无限循环的快乐数,而这个数字是4,只需要在数字为4的时候结束即可,代码如下:
public boolean isHappy2(int n) {
if(n == 1) return true;
if(n == 4) return false;
if(n<10&&Math.pow(n,2)<10) return false;
int value = 0;
while(n!=0){
value += Math.pow(n%10,2);
n = n/10;
}
return isHappy2(value);
}