Floyd 判圈 算法

来源:互联网 发布:网络写手. 正规的网站 编辑:程序博客网 时间:2024/04/29 23:50

转自 leetcode 202------判断开心数

给定任意正数,比如19。

计算该正数各位上的数字的平方和,即12 + 92 = 82

重复第二步,对计算结果进行计算,得到

  • 82 + 22 = 68
  • 62 + 82 = 100
  • 12 + 02 + 02 = 1如果最后能够得到1,则认为是开心数。


    总结:

    1、

    int digitSquareSum(int n) {    int sum = 0, tmp;    while (n) {        tmp = n % 10;        sum += tmp * tmp;        n /= 10;    }    return sum;}bool isHappy(int n) {    int slow, fast;    slow = fast = n;    do {        slow = digitSquareSum(slow);        fast = digitSquareSum(fast);        fast = digitSquareSum(fast);    } while(slow != fast);    if (slow == 1) return 1;    else return 0;}

    这是一个单向链表问题,使用Floyd判圈算法,可以计算出其中有没有环。

    链接:http://blog.csdn.net/javasus/article/details/50015687

    http://www.siafoo.net/algorithm/10

    2、基础证明

    • 为什么会成环
      • for nin [1,10), g(n)>=n, since g(n)=n*n>=nwith equality hold onlyfor n=1
      • for other n with only highest digit nonzero (eg. 10, 90, 500, 4000,20000, etc), g(n)<n
      • and we can factor n into sum of numbers with only highest digitnonzero, eg. 12045 = 10000 + 2000 + 40 + 5

      in this way, we can show for any n>=100, g(n) < n
      对于任意正数n,跳转结果是有限的


    • 环的大小
      input: n (positive integer)func g = digitSquareSumwhile n>99    n = g(n)output: HappyTable(n)
      可以计算[1,100]里面的所有情况,从而得到环的大小,以及这100个数的对应是否是开心数的表。

    • 使用表或者数组存储每步的计算结果和判断结果
      The common choice is to use map or set to check if there is a loop. since the maximum sum is no greater than 2x2 + 9x9x9 (2,999,999,999), we can use a 1000 lengh hashtable . It's not O(1) space but it's faster than the fast-slow pointer solution.

      class Solution {public:    int tran(int n){        int ans = 0;        while(n){            ans += pow(n%10, 2);            n/=10;        }        return ans;    }    bool isHappy(int n) {        bool rep[1000];        memset(rep, 0, sizeof(rep));        n = tran(n);        while(!rep[n]){            rep[n] = true;            if(n == 1)                return true;               n = tran(n);        }        return false;    }};

    • public boolean isHappy(int n) {    Set<Integer> inLoop = new HashSet<Integer>();    int squareSum,remain;    while (inLoop.add(n)) {        squareSum = 0;        while (n > 0) {            remain = n%10;            squareSum += remain*remain;            n /= 10;        }        if (squareSum == 1)            return true;        else            n = squareSum;    }    return false;}

  • 0 0
    原创粉丝点击