总结
-
三题知识点
-
取出一个数的所有个位数,while(num > 0) { int d = num % 10; num = num / 10;}
-
一个数num包含某个因数factor,则num % factor == 0 ; 若全部是由这个因数组成,则num不断去 / factor, 最后得到的数为1。
-
若一个数不包含某个因数,则num % factor != 0
-
涉及思想
-
定义一个计算法则,即一个映射,这个映射也可以看成一个指针;
-
如果从一个数开始,经过计算法则出现无限数字无限循环,相当于链表出现了环
-
链表中,查找环,快慢指针
题目 202_快乐数 简单
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。
示例:
输入:19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
思路
-
怎么判断是不是无限循环
-
转换为:每个数字都会根据平方和指向另一个数字,从任意数字开始进行各位平方和的迭代操作,就相当于在链表上游走。如果无线循环但始终变不到1,就说明链表走到了环。
-
为什么呢?为什么无线循环就一定是走到了环呢?而不是链表上的数字越来越大?
-
不会有一个一直增长的链表
-
循环链表,用快慢指针破解
// 怎么判断是不是无限循环,即什么情况下会无限循环
// 如果数的平方和指向下一个数 ——> 数的平方和指向下一个数 ——> 形成环
// 形成环就会无限循环
// 链表的next:在这里是数平方和指向下一个数
// 环用快慢双指针判断
// 如果相等,跳出循环,则跳出循环,肯定不是快乐数
// 如果中途slow == 1, 也跳出循环,是快乐数
// 1 也会造成循环,如果不在1初判断是否等于1,所以不加判断是否等于1,反正快慢指针会在1出相遇,跳出循环,判断是否等于1就好。
-
-
三种情况:
- 数的平方和有1的情况,且没有除1以外的环
- 数的平方和没有1,有环
- 数越来越大,无限大(经证明,数最后 不可能接近无限大)
-
反正1也会造成环,即slow 会和fast相遇,退出循环,最后判断是不是1就好了
class Solution {
public boolean isHappy(int n) {
int slow = n, fast = getNext(n);
while(slow != fast) {
slow = getNext(slow);
fast = getNext(getNext(fast));
}
return slow == 1;
}
private int getNext(int num) {
int sum = 0;
while(num > 0) {
int d = num % 10;
sum += d * d;
num = num / 10;
}
return sum;
}
}
- 我碰到1的时候就跳出循环,最后判断是1跳出的循环还是其他循环造成的快慢指针相等跳出的循环。
class Solution {
public boolean isHappy(int n) {
int slow = n, fast = getNext(n);
while(slow != 1 && slow != fast) {
slow = getNext(slow);
fast = getNext(getNext(fast));
}
return slow == 1;
}
private int getNext(int num) {
int sum = 0;
while(num > 0) {
int d = num % 10;
sum += d * d;
num = num / 10;
}
return sum;
}
}
258. 各位相加
给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。
示例:
输入: 38
输出: 2
解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。
class Solution {
public int addDigits(int num) {
// 结束条件 num < 10
int currNum = num;
while(currNum >= 10) {
currNum = getNext(currNum);
}
return currNum;
}
private int getNext(int num) {
int sum = 0;
while(num > 0) {
int d = num % 10;
sum += d;
num = num / 10;
}
return sum;
}
}
263. 丑数_简单
编写一个程序判断给定的数是否为丑数。
丑数就是只包含质因数 2, 3, 5 的正整数。
示例 1:
输入: 6
输出: true
解释: 6 = 2 × 3
示例 2:
输入: 8
输出: true
解释: 8 = 2 × 2 × 2
示例 3:
输入: 14
输出: false
解释: 14 不是丑数,因为它包含了另外一个质因数 7。
思路
- 如果一个数是丑数,则一定满足:num = 2 ^ i * 3 ^ j * 5 ^ k,
- 用2, 3, 5不断去除,如果是丑数,则最后肯定是 num = 1 * (2 or 3 or 5) / (2 or 3 or 5) == 1, 1 % (2 or 3 or 5) != 0 跳出循环
- 结束条件:
- 2, 3, 5都被除过了,for() 保证2, 3, 5一定都会除
- 剩下的除数 如果是1 ,即 1 % (2 or 3 or 5) == 1 则是丑数
- 剩下的除数 如果不是1,即 14 % (2 or 3 or 5) = 2 * 7 + 0 ; 7 % (2 or 3 or 5) = 7 , 则不是丑数;
class Solution {
public boolean isUgly(int num) {
if(num <= 0) return false;
int[] factors = new int[]{2, 3, 5};
for(int factor : factors) {
while(num % factor == 0) {
num = num / factor;
}
}
return num == 1;
}
}