[LC]202. happy numbers


一、问题描述

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 ;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值