Leetcode 快乐数

  • 编写一个算法来判断一个数 n 是不是快乐数。

    「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为  1,那么这个数就是快乐数。

    如果 n 是快乐数就返回 True ;不是,则返回 False 。

  示例

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

代码一

class Solution {
public:
    bool isHappy(int n) {
        if(n <= 0) return false;

        int time = 0; // 无限循环次数
        int sum = 0; // 平方和
        while(sum != 1){
            sum = 0; 
            while(n){
                int yushu = n % 10;
                n = n / 10;
                sum += yushu*yushu;
            }
            time += 1;
            n = sum;
            if(time > 30) return false; // 循环上限设为30
        }

        return true;
    }
};

代码二

定义一个哈希表,来检测循环。

class Solution {
public:
    bool isHappy(int n) {
        if(n <= 0) return false;

        unordered_map<int, int> MyMap;
        int sum = 0; // 平方和
        while(sum != 1){
            // 找到当前要求平方和的数n,说明有循环,那么直接返回false,否则将它放入vector中
            if(MyMap.find(n) != MyMap.end()) return false;
            else MyMap[n] = n;

            sum = 0; 
            while(n){
                int yushu = n % 10;
                n = n / 10;
                sum += yushu*yushu;
            }
            n = sum;
        }
        return true;
    }
};
class Solution {
public:
    bool isHappy(int n) {
        if(n <= 0) return false;

        unordered_map<int, bool> MyMap;
        int sum = 0; // 平方和
        while(sum != 1){
            // 找到当前要求平方和的数n,说明有循环,那么直接返回false,否则将它放入vector中
            if(MyMap[n]) return false;
            else MyMap[n] = true;

            sum = 0; 
            while(n){
                int yushu = n % 10;
                n = n / 10;
                sum += yushu*yushu;
            }
            n = sum;
        }
        return true;
    }
};

 

代码三

使用vector来判断是否有循环。有循环直接返回false。

class Solution {
public:
    bool isHappy(int n) {
        if(n <= 0) return false;

        vector<int> vec;
        int sum = 0; // 平方和
        while(sum != 1){
            // 在vec中找到当前要求平方和的数n,说明有循环,那么直接返回false,否则将它放入vector中
            if(find(vec.begin(), vec.end(), n) != vec.end()) return false;
            else vec.push_back(n);

            sum = 0; 
            while(n){
                int yushu = n % 10;
                n = n / 10;
                sum += yushu*yushu;
            }
            n = sum;
        }
        return true;
    }
};

 代码四

快慢指针法。快指针每次移动两格,慢指针每次移动一格。最终结果:

  • 如果n是一个快乐数,那么快指针先到达数字1。
  • 如果n不是一个快乐数,就会出现环,那么快慢指针会在某一个节点相遇。
class Solution {
public:
    int GetNext(int n){
        int sum = 0;
        while(n){
            sum += (n % 10) * (n % 10);
            n = n / 10;
        }
        return sum;
    }

    bool isHappy(int n) {
        int slow_runner = n;
        int fast_runner = GetNext(n);

        while(fast_runner != 1 && slow_runner != fast_runner){
            slow_runner = GetNext(slow_runner);
            fast_runner = GetNext(GetNext(fast_runner)); // 快指针通过嵌套得到下一个值
        }

        return fast_runner == 1;
    }
};

 

posted @ 2020-05-11 11:28  Crazy_Coding  阅读(74)  评论(0)    收藏  举报