一、问题描述
Write an algorithm to determine if a number is "happy".
A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.
Example: 19 is a happy number
- 12 + 92 = 82
- 82 + 22 = 68
- 62 + 82 = 100
- 12 + 02 + 02 = 1
二、我的思路
用一个ArrayList存储中间变量,每次判断一下当前中间变量是否出现过来判断是否endless。如果中间变量是1则是happy number。
class Solution {
public boolean isHappy(int n) {
List<Integer> appeared = new ArrayList<Integer>();
int cur_n;
while(n != 1 && (!appeared.contains(n))){
appeared.add(n);
cur_n = 0;
while(n > 0){
cur_n += (n%10) * (n%10);
n = n/10;
}
n = cur_n;
}
return n == 1;
}
}
反思:
1. 用ArrayList存储是否是最好的?ArrayList是怎么实现contains函数的?
A:不是最好的,参见这篇文章http://blog.csdn.net/fenglibing/article/details/9021201。其中提到慎用ArrayList的contains方法。因为该方法的实现调用了很多indexOf方法,也就是说最坏情况下可能要查找多次List这么长的内容。而HashSet用的HashTable,所以速度会快很多
2. n%10可以先用变量存一下,就不用计算两次了。
修正后:
class Solution {
public boolean isHappy(int n) {
Set<Integer> appeared = new HashSet<Integer>();
int cur_n, remained;
while(n != 1 && (!appeared.contains(n))){
appeared.add(n);
cur_n = 0;
while(n > 0){
remained = (n%10);
cur_n += remained * remained;
n = n/10;
}
n = cur_n;
}
return n == 1;
}
}
再看下高票解法,虽然思路一样,但是实现就能看出差距吖!他直接拿HashSet的add方法的返回参数做跳出循坏的条件了
public boolean isHappy(int n) {
Set<Integer> inLoop = new HashSet<Integer>();
int squareSum,remain;
while (inLoop.add(n)) {
squareSum = 0;
while (n > 0) {
remain = n%10;
squareSum += remain*remain;
n /= 10;
}
if (squareSum == 1)
return true;
else
n = squareSum;
}
return false;
}
三、淫奇技巧
1. 空间上O(1)解法,思路借鉴了判断单链表是否成环:一个指针走一步,另一个走两步,当两个人当值相等了(且不是1)就false.
public class Solution {
public boolean isHappy(int n) {
int x = n;
int y = n;
while(x>1){
x = cal(x) ;
if(x==1) return true ;
y = cal(cal(y));
if(y==1) return true ;
if(x==y) return false;
}
return true ;
}
public int cal(int n){
int x = n;
int s = 0;
while(x>0){
s = s+(x%10)*(x%10);
x = x/10;
}
return s ;
}
}