leetcode202(Floyd判圈算法(龟兔赛跑算法))

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.

一个快乐数是这样定义的,规则如下:由一个整数开始,之后由整数每一位数字的平方和的总和代替这个数,然后重复这个过程,直到最后是1为止,或者这个循环是一个没有包含1的死循环。这些过程中最终结果是1的这些数被称为快乐数。

Example: 19 is a happy number

  • 12 + 92 = 82
  • 82 + 22 = 68
  • 62 + 82 = 100
  • 12 + 02 + 02 = 1

这个题目真的我没有想到好的思路,能想到的几点说一下,平方的值只有从0-9这几个数的平方,所以,定一个固定的数组一定比平方的计算要快,直接可以用数组下标取出最后的结果。

这道题难在如何判断它是一个死循环,而且还是没有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判圈算法(龟兔赛跑算法)

先往简单了说,就是判断有没有环,定两个起始位置一样的指针,一个跑的慢每次跑一个循环,一个跑的快每次跑相当于跑两个循环,一旦他们出现相同之后,那么就肯定是有环了,然后我们就看责怪环是不是1即可,这个算法最大的一个优点是时间复杂度低,空间复杂度也低,你不需要保存每一次出现的值然后和前面的值作比较。

具体算法的讲解我这边直接贴上地址,转载自:

http://blog.csdn.net/wall_f/article/details/8780209

说实话我很喜欢这个算法,确实棒极了!

时间: 2024-08-04 18:14:58

leetcode202(Floyd判圈算法(龟兔赛跑算法))的相关文章

Floyd判圈算法(判断链表是否含环)

Floyd判圈算法 简介 Floyd判圈算法,也称龟兔赛跑算法,可用于判断链表.迭代函数.有限状态机是否有环.如果有,找出环的起点和大小.时间复杂度O(n),空间复杂度O(1). 可以先思考一下,假设有一个圆形的跑道周长为\(C\),A和B从同一个起点,分别以\(v\)和\(2v\)的速度同向出发,可以知道,因为B比A跑得快而且跑道是环形的,所以接下来一定存在某一时刻,B和A相遇,这时候,B跑过的总距离\(S_B\)减去A跑的总距离\(S_A\)一定是\(C\)的整数倍.即: \(S_B-S_A

Floyd判圈算法

Floyd判圈算法(Floyd Cycle Detection Algorithm),又称龟兔赛跑算法(Tortoise and Hare Algorithm),是一个可以在有限状态机.迭代函数或者链表上判断是否存在环,求出该环的起点与长度的算法.该算法据高德纳称由美国科学家罗伯特·弗洛伊德发明,但这一算法并没有出现在罗伯特·弗洛伊德公开发表的著作中.  如果有限状态机.迭代函数或者链表上存在环,那么在某个环上以不同速度前进的2个指针必定会在某个时刻相遇.同时显然地,如果从同一个起点(即使这个起

[LeetCode] 287. Find the Duplicate Number(Floyd判圈算法)

传送门 Description Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one. Note: You mu

uva 11549计算器谜题(floyd判圈算法)

 题意:有个老式计算器,每次只能记住一个数字的前n位.现在输入一个整数k,然后反复平方,一直做下去,能得到的最大数是多少.例如,n=1,k=6,那么一次显示:6,3,9,1... 思路:这个题一定会出现循环,所以一个个模拟,遇到相同的就再之前所有数中找最大的输出即可. 最容易想到的就是set判重,一开始k直接生算每次除十......超时 然后看了书,用string,ac,很方便但是时间达到了4s,果然string和stringstream好慢啊......... 又改成了记录k*k的每一位,

SGU 455 Sequence analysis(Cycle detection,floyd判圈算法)

题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=455 Due to the slow 'mod' and 'div' operations with int64 type, all Delphi solutions for the problem 455 (Sequence analysis) run much slower than the same code written in C++ or Java. We do not gua

sgu 455. Sequence analysis (floyd 判圈算法,O(1)空间复杂度求循环节)

455. Sequence analysis Time limit per test: 1 second(s)Memory limit: 4096 kilobytes input: standardoutput: standard Due to the slow 'mod' and 'div' operations with int64 type, all Delphi solutions for the problem 455 (Sequence analysis) run much slow

UVa 11549 计算器谜题(Floyd判圈算法)

https://vjudge.net/problem/UVA-11549 题意: 有一个老式计算器,只能显示n位数字,输入一个整数k,然后反复平方,如果溢出的话,计算器会显示结果的最高n位.如果一直这样做下去,能得到的最大数是多少? 思路: 这个肯定是会循环的. 比较普通的做法就是用set来判断是否出现过来终止循环. 另一个高效算法:Floyd判圈算法!! 想象一下,假设有两个小孩子在一个“可以无限向前跑”的跑道上赛跑,同时出发,但其中一个孩子的速度是另一个两倍.如果跑到是直的,跑得快的小孩永远

UVA 11549 Calculator Conundrum Floyd判圈

题目链接:点击打开链接 题意: 输入n k,表示计算器能显示n位数字,初始有一个数字k 每次操作 k = k^2, 若超出n位则截取前n位. 求能获得的最大数字. 思路: 首先我们能判断这个操作一定存在循环. 那么如何终止循环,利用Floyd判圈法 让两个循环child1和child2刚开始都为k,然后child1每次变换一次,child2每次变换2次: 这样当child1再次等于child2时说明已经至少经过一个循环节了,因为child2已经从后面赶上child1了 import java.i

UVa 1594 (Floyd判圈) Ducci Sequence

大白书上P42那个计算器的题目就用到了这个办法,Floyd判圈法. 当然,用STL里的map也是可以的. 1 #include <cstdio> 2 #include <cmath> 3 4 const int maxn = 20; 5 int n; 6 int a[maxn], b[maxn], c[maxn]; 7 8 void next(int a[]) 9 { 10 for(int i = 0; i < n - 1; i++) a[i] = std::abs(a[i]