LeetCode 202 快乐数——Floyd判圈算法

  • 链接 : 快乐数
  • 题意 :
    在这里插入图片描述
  • 思路:
    (1)只要把数位平方和相加,判断是否等于1即可。循环判断则用set即可。
    代码:
class Solution {
    
    
    int check(int n){
    
    
        int ans = 0;
        while(n){
    
    
            int tmp = n % 10;
            ans += pow(tmp,2);
            n /= 10;
        }
        return ans;
    }
public:
    bool isHappy(int n) {
    
    
        bool ans = false;
        set<int> vis;
        vis.insert(n);
        while(true){
    
    
            int tmp = check(n);
            if(tmp == 1){
    
    
                ans = true;
                break;
            }
            if(vis.count(tmp)){
    
    
                break;
            }
            vis.insert(tmp);
            n = tmp;
        }
        return ans;
    }
};

(2)Floyd判圈方法。
刚开始没想到,后来看了官方题解,想到这个方法,在刘汝佳大神的蓝书里面有讲到。 P44,UVa11594这道题。
在这里插入图片描述
简单来说,a和b在一条直线上跑步,b的速度是a的二倍。如果这条直线后面是一个环,那么b肯定能追上a。
所以可以设tmp1 = check(tmp1), tmp2 = check(check(tmp2))。如果tmp2 == tmp1,那么就有环咯。

class Solution {
    
    
    int check(int n){
    
    
        int ans = 0;
        while(n){
    
    
            int tmp = n % 10;
            ans += pow(tmp,2);
            n /= 10;
        }
        return ans;
    }
public:
    bool isHappy(int n) {
    
    
        bool ans = false;
        int tmp1 = n, tmp2 = check(n);
        while(true){
    
    
            tmp1 = check(tmp1);
            tmp2 = check(check(tmp2)); 
            if(tmp1 == 1){
    
    
                ans = true;
                break;
            }
            if(tmp1 == tmp2){
    
    
                break;
            }
        }
        return ans;
    }
};

本题很简单,但是考虑到有Floyd判圈这个省内存空间的好办法,就有研究的价值了。

  • 遇到的问题:
    最开始我赋值 tmp1 = n, tmp2 = check(tmp1),但是这样根本不是以二倍的速度。
    蓝书上的初始化是 tmp1 = tmp2 = n, 然后 tmp1 check一次,tmp2连续check 2次。不过官方题解 初始化 tmp1 = n , tmp2 = check(n),这样对,并且更快。

Guess you like

Origin blog.csdn.net/qq_39763472/article/details/105870795