leetcode题解--#202.快乐数

题目链接

题目描述:编写一个算法来判断一个数是不是“快乐数”。
一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。

实例:

输入: 19
输出: true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

题解:
  常规方法当然是通过哈希表判重,即通过set(c++)记录每次计算得到的数来判断是否跳出循环。本文将介绍另一种方法,也就是利用Floyd Cycle思想来判断是否是1跳出循环。通俗来讲,就是快慢指针。
  题目给出了快乐数的定义,注意:是快乐数最终会变成1;若不是则可能掉入死循环。意味着我们要思考如何跳出循环。这时,利用快慢指针可破循环。为什么这么说?顾名思义,可以假设快慢指针在同一起点(也就是出入值n)出发,快指针一次计算两步,慢指针一次计算一步,那么,在某一时刻,无论它是不是快乐数,快慢指针都会相遇。也就意味着循环周期结束。这时,我们可以跳出循环,判断是否是1导致跳出循环。
  注:这里快慢指针分别走几步没有限制,掌握思想即可。当然,快两步慢一步效率相对高一些。

算法

class Solution {
public:
    bool isHappy(int n) {
        int slow = n, fast = n;
        do{
            slow = countNum(slow);
            fast = countNum(fast);
            fast = countNum(fast);
        }while(slow != fast);
        if(slow == 1){
            return true;
        }
        else{
            return false;
        }
    }

    int countNum(int n ){
        int sum = 0, temp = 0;
        while(n > 0){
            temp = n % 10;
            sum += pow(temp , 2);
            n = n / 10;
        }
        return sum;
    }
};

提示:当输入数为快乐数时,快慢指针最后一定会到达1,意味着快指针会先到达1,然后等着慢指针到达1再跳出循环。这使得我们会多出一部分运算,所以我们可以在快指针到达1时就跳出循环。

改进:

class Solution {
public:
    bool isHappy(int n) {
        int slow = n, fast = n;
        do{
            slow = countNum(slow);
            fast = countNum(fast);
            fast = countNum(fast);
            if(fast == 1){
                return true;
            }
        }while(slow != fast);
        if(slow == 1){
            return true;
        }
        else{
            return false;
        }
    }

    int countNum(int n ){
        int sum = 0, temp = 0;
        while(n > 0){
            temp = n % 10;
            sum += pow(temp , 2);
            n = n / 10;
        }
        return sum;
    }
};

若还有疑问可以去英文版leetcode的discuss区看大神们的解答!

本人blog:http://breadhunter.gitee.io

你可能感兴趣的:(数据结构与算法,leetcode题解,leetcode,算法,指针,c++)