zoukankan      html  css  js  c++  java
  • Leetcode 202. Happy Number

    202. Happy Number

    • Total Accepted: 78171
    • Total Submissions: 208635
    • Difficulty: Easy

    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

    思路:

    对于一个数n,如果n不是Happy Number,那么在求n各数位平方和以及求在n之后的每个数的各数位平方和的过程中,一定会产生循环。Discuss中相关的证明

    原文如下:

    Earlier posts gave the algorithm but did not explain why it is valid mathematically, and this is what this post is about: present a "short" mathematical proof.
    
    First of all, it is easy to argue that starting from a number I, if some value - say a - appears again during the process after k steps, the initial number I cannot be a happy number. Because a will continuously become a after every k steps.
    
    Therefore, as long as we can show that there is a loop after running the process continuously, the number is not a happy number.
    
    There is another detail not clarified yet: For any non-happy number, will it definitely end up with a loop during the process? This is important, because it is possible for a non-happy number to follow the process endlessly while having no loop.
    
    To show that a non-happy number will definitely generate a loop, we only need to show that for any non-happy number, all outcomes during the process are bounded by some large but finite integer N. If all outcomes can only be in a finite set (2,N], and since there are infinitely many outcomes for a non-happy number, there has to be at least one duplicate, meaning a loop!
    
    Suppose after a couple of processes, we end up with a large outcome O1 with D digits where D is kind of large, say D>=4, i.e., O1 > 999 (If we cannot even reach such a large outcome, it means all outcomes are bounded by 999 ==> loop exists). We can easily see that after processing O1, the new outcome O2 can be at most 9^2*D < 100D, meaning that O2 can have at most 2+d(D) digits, where d(D) is the number of digits D have. It is obvious that 2+d(D) < D. We can further argue that O1 is the maximum (or boundary) of all outcomes afterwards. This can be shown by contradictory: Suppose after some steps, we reach another large number O3 > O1. This means we process on some number W <= 999 that yields O3. However, this cannot happen because the outcome of W can be at most 9^2*3 < 300 < O1.

    方法一:直接用定义。但要注意map中没有对应的键值映射时,返回的是0,所以要提前判断当前要做映射的键是否是0。

    方法二:其实在上面的证明中也可以知道,只要当前的数n不是1位数,根据2+d(D)<D,可以知道以后的数相较于前一个数数位都是要减少的,最终变为1位数。所以,只要找到在[1,9]中是Happy Number的数就可以了。(1和7是Happy Number)。因此,只要不断循环,总是可以收敛到1个数位的。

    方法三:用Floyd's cycle-finding algorithm。本质是2个快慢指针,快指针如果和慢指针相遇,说明存在环。

    代码:
    方法一:

     1 class Solution {
     2 public:
     3     bool isHappy(int n) {
     4         map<int,int> thash;
     5         while(n&&!thash[n]){
     6             thash[n]=n;
     7             int temp=0,low;
     8             while(n){
     9                 low=n%10;
    10                 temp+=low*low;
    11                 n/=10;
    12             }
    13             n=temp;
    14         }
    15         if(n==1){
    16             return true;
    17         }
    18         return false;
    19     }
    20 };

    方法二:

     1 class Solution {
     2 public:
     3     int next(int n){
     4         int temp=0,low;
     5         while(n){
     6             low=n%10;
     7             temp+=low*low;
     8             n/=10;
     9         }
    10         return temp;
    11     }
    12     bool isHappy(int n) {
    13         while(n>9){
    14             n=next(n);
    15         }
    16         if(n==1||n==7){
    17             return true;
    18         }
    19         return false;
    20     }
    21 };

    方法三:

     1 class Solution {
     2 public:
     3     int next(int n){
     4         int temp=0,low;
     5         while(n){
     6             low=n%10;
     7             temp+=low*low;
     8             n/=10;
     9         }
    10         return temp;
    11     }
    12     bool isHappy(int n) {
    13         int fast=next(n),slow=n;
    14         while(fast!=slow){
    15             slow=next(slow);
    16             fast=next(next(fast));
    17         }
    18         if(fast==1){
    19             return true;
    20         }
    21         return false;
    22     }
    23 };
  • 相关阅读:
    详细描述一下 Elasticsearch 索引文档的过程 ?
    elasticsearch 索引数据多了怎么办,如何调优,部署 ?
    elasticsearch 了解多少,说说你们公司 es 的集群架构,索 引数据大小,分片有多少,以及一些调优手段 ?
    Dubbo 和 Dubbox 之间的区别?
    Dubbo 支持服务降级吗?
    Pipeline 有什么好处,为什么要用 pipeline?
    为什么redis 需要把所有数据放到内存中?
    你对线程优先级的理解是什么?
    在 java 中 wait 和 sleep 方法的不同?
    一个线程运行时发生异常会怎样?
  • 原文地址:https://www.cnblogs.com/Deribs4/p/5671843.html
Copyright © 2011-2022 走看看