小益的判断梦想数
题目描述
梦想数定义,一直对数每位的平方进行求和操作,当循环中出现 1 则为梦想数
输入一个正整数,判断其是否为梦想数
例: 19
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
即 19 为梦想数
样例输入
19
样例输入
忘了。。你能算对就行
思路
梦想数好找,关键在于如何判断不是梦想数
LeetCode原题
通过计算(测试)可以发现:
当一个数为非梦想数时候,后面一定会出现循环的数(曾经出现过的)
基本思路:存下出现过的数,判断是否重复出现,出现则为非梦想数
注:需要先判断是否为 1, 因为梦想数后面也是一直循环 1
另外可能会出现大量的个位数的平方和计算
我们可以采用预处理数组存好 0 - 9 的平方和提高时间效率
编码
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Main {
private static int[] a = new int[10]; // 记录 0 - 9 的平方和
private static Set<Integer> set = new HashSet<>(); // 记录出现过的数
private static void init() { // 预处理平方和,减少计算量
for(int i = 1; i < 10; ++i) {
a[i] = i*i;
}
}
private static int getSum(int x) { // 一次求每位的平方和操作
int sum = 0;
while(x != 0) {
sum += a[x%10];
x /= 10;
}
return sum;
}
private static boolean isDreamNum(int x) { // 递归层数不深所以未采用循环
if(x == 1) return true;
if(set.contains(x)) return false;
set.add(x);
return isDreamNum(getSum(x));
}
public static void main(String[] args) {
init();
Scanner scn = new Scanner(System.in);
int x = scn.nextInt();
if(isDreamNum(x)) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
}