其他分享
首页 > 其他分享> > 202. 快乐数

202. 快乐数

作者:互联网

class Solution {
public:
    bool isHappy(int n) {
        int ans=0;
        for(int i = 0 ; i< 100;i++)
        {
            while(n>0)
            {
                ans += (n%10)*(n%10);
                n = n /10;
            }
            n = ans;
            if(n==1)
                return true;
        }
        return false;
    }
};

上边这个是纯属娱乐的暴力解法,但有一点是需要学习的,就是你如何把一个数的每一位都给他拿出来,注意是每一位都拿!!!这个时候就可以先拿最后一位,然后把其他的依次变成最后一位再拿。这么个小过程好像可以用递归写,因为它符合把一个问题减小了一个常数复杂度,剩下的问题仍能这么处理直到变成最小的。写法如下了:

  //计算一个数的每一个数字加起来的和
  int everyNumAdd(int num) {
      if (num == 0) { return 0; }

      return (num % 10) + everyNumAdd(num / 10);
  }

而需要学的点就是取模取到最后一位,然后除以10,再次取模,得到原来数字的倒数第二位,直到得到第一位。而如果想要的得到他特定的某一位(比如千位)这种可以直接除以特定的100然后再取模。而你获得每一位并不是依次获得个十百千万....然后相加的,一个未知数你哪知道哪是个头啊。

上边是把死循环量化了,一百次如果都没变成1,快乐起来,以后基本上就不会快乐起来了。对于绝大多数的案例是可以ok的,但是这种投机取巧看看就可以了。

死循环,你得多思考一步为什么会有这么个死循环?首先这个数字他不会变得很大,这个很简单一个数的平方最大81,他是一个100位数的数字也就八千多,但是肯定是远比这个要小的,所以说他不可能一直增大到很大,那么既然是死循环了,说明他至多取遍这八千多个数,然后重复取,形成一个环路。那么就是因为他的数字进入了一个循环由于他一波操作变成了一个数n,这个数字变了一会又一次回到n,那么接下来就开始转圈圈了。所以说你就是判断是否进入了这么一个圈就行了。那么最简单的思路就是把出现过的数字都先放起来,当塞进去一个数字发现里边已经有了的时候那就说明进圈了。

class Solution {
public:
    int find(int x){    //求一个数每个位置上的数字的平方和
        int res=0;
        while(x){
            res+=(x%10)*(x%10);
            x/=10;
        }
        return res;
    }

    bool isHappy(int n) {
        unordered_set<int> hash;    //将每个答案存进哈希表,方便后续判断
        int t=find(n);
        while(t>1){ 
            if(hash.count(t))   //判断此结果是否在哈希表中出现过
            return false;
            hash.insert(t); //插入元素
            t=find(t);
        }

        return true;
    }
};

作者:vvonderful-gangulyop0
链接:https://leetcode-cn.com/problems/happy-number/solution/kuai-le-de-cha-xi-by-vvonderful-gangulyo-dgix/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
    int bitSquareSum(int num){
        if(num == 0){return 0;}

        return (num % 10) * (num % 10) + bitSquareSum(num / 10);
    }

    bool isHappy(int n) {
        unordered_set<int> hash;

        do{
            n = bitSquareSum(n);
            if(hash.count(n)){
                return false;
            }
            hash.insert(n);
        }while(n > 1);

        return true;
        
    }
};
上边是我自己的写法。

而找出循环的另一种方法就是如下的快慢指针法:

因为你只要有个循环,说白了就是有个圈,那么我一个快的一个慢的,最后肯定能遇上。就是这么个思路去检验是否有环。就是类似于之前的棒棒糖结构。另外如果这个数是快乐数,最后也是一个棒棒糖,只是糖的部分只有个数字1。

解题思路:
方法:
使用 “快慢指针” 思想,找出循环:“快指针” 每次走两步,“慢指针” 每次走一步,
当二者相等时,即为一个循环周期。此时,判断是不是因为 1 引起的循环,
是的话就是快乐数,否则不是快乐数。
注意:此题不建议用集合记录每次的计算结果来判断是否进入循环,
因为这个集合可能大到无法存储;另外,也不建议使用递归,
同理,如果递归层次较深,会直接导致调用栈崩溃。
不要因为这个题目给出的整数是 int 型而投机取巧。

代码:
C++

class Solution {
public:
    int bitSquareSum(int n) {
        int sum = 0;
        while(n > 0)
        {
            int bit = n % 10;
            sum += bit * bit;
            n = n / 10;
        }
        return sum;
    }
    
    bool isHappy(int n) {
        int slow = n, fast = n;
        do{
            slow = bitSquareSum(slow);
            fast = bitSquareSum(fast);
            fast = bitSquareSum(fast);
        }while(slow != fast);
        
        return slow == 1;
    }
};


作者:linux-man
链接:https://leetcode-cn.com/problems/happy-number/solution/shi-yong-kuai-man-zhi-zhen-si-xiang-zhao-chu-xun-h/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

其实平时说的循环for,while循环多数情况下都“环”,而只有死循环才是真正的成了环。

思路:为什么是死循环   进入了一个循环(圈)走不出来   需要判断是否走进了一个圈   那就用快慢指针  考虑不是死循环的情况对于快慢指针走代码跑出来是什么样的   做出最后的判断

标签:10,202,return,int,num,bitSquareSum,while,快乐
来源: https://blog.csdn.net/yinianbaifaI/article/details/121303162