202. Happy Number [easy] (Python)

题目链接

https://leetcode.com/problems/happy-number/

题目原文

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

题目翻译

写一个程序来判断一个数字是否是“happy”的。

所谓 happy number,是被这样的过程定义的数字:初始时有一个正整数,用该整数每位数字的平方之和代替这个整数,重复该过程直至数字变为1(之后不再变化),或者陷入一个无尽的循环但该循环不包括1。那些能终止于1的数字就称为 happy number。

比如:19就是一个 happy number,因为
12+92=82
82+22=68
62+82=100
12+02+02=1

思路方法

思路一

按照“happy number”的定义,直接循环计算各位平方和,观察是否收敛到1,若是则是 happy number。为了判断循环是否开始重复,要用一个字典(dict)或集合(set)来保存已经出现的数字,dict的效率更高。

代码一

class Solution(object):
    def isHappy(self, n):
        """ :type n: int :rtype: bool """
        num_dict = {}

        while True:
            num_dict[n] = True
            sum = 0
            while(n>0):
                sum += (n%10)*(n%10)
                n /= 10
            if sum == 1:
                return True
            elif sum in num_dict:
                return False
            else:
                n = sum

通过分析该问题,利用一些分析结果,可以对算法进行优化。比如利用10以内的happy number只有1和7,或者先求出100以内的所有happy number等。

代码二

class Solution(object):
    def isHappy(self, n):
        """ :type n: int :rtype: bool """
        happySet = set([1, 7, 10, 13, 19, 23, 28, 31, 32, 44, 49, 68, 70, 79, 82, 86, 91, 94, 97])

        while n>99:
            n = sum([int(x) * int(x) for x in list(str(n))])
        return n in happySet

思路二

上面的思路判断是否出现循环可能用到大量的额外空间,如果想要压缩空间复杂度到 O(1),可以考虑用弗洛伊德环检测算法(Floyd Cycle Detection Algorithm),代码如下。

代码

class Solution(object):
    def isHappy(self, n):
        """ :type n: int :rtype: bool """
        slow = fast = n
        while True:
            slow = self.squareSum(slow)
            fast = self.squareSum(fast)
            fast = self.squareSum(fast)
            if slow == fast:
                break
        return slow == 1

    def squareSum(self, n):
        sum = 0
        while(n>0):
            tmp = n % 10
            sum += tmp * tmp
            n /= 10
        return sum

说明
关于该方法的一些解释,可以参考:
https://leetcode.com/discuss/71625/explanation-those-posted-algorithms-mathematically-valid

PS: 新手刷LeetCode,新手写博客,写错了或者写的不清楚还请帮忙指出,谢谢!
转载请注明:http://blog.csdn.net/coder_orz/article/details/51315486

    原文作者:coder_orz
    原文地址: https://blog.csdn.net/coder_orz/article/details/51315486
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞