[leetcode] 202.happy number 快乐数
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:
input: 19
output: true
explanation:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
credits:
special thanks to and for adding this problem and creating all test cases.
这道题定义了一种快乐数,就是说对于某一个正整数,如果对其各个位上的数字分别平方,然后再加起来得到一个新的数字,再进行同样的操作,如果最终结果变成了1,则说明是快乐数,如果一直循环但不是1的话,就不是快乐数,那么现在任意给我们一个正整数,让我们判断这个数是不是快乐数,题目中给的例子19是快乐数,那么我们来看一个不是快乐数的情况,比如数字11有如下的计算过程:
1^2 + 1^2 = 2
2^2 = 4
4^2 = 16
1^2 + 6^2 = 37
3^2 + 7^2 = 58
5^2 + 8^2 = 89
8^2 + 9^2 = 145
1^2 + 4^2 + 5^2 = 42
4^2 + 2^2 = 20
2^2 + 0^2 = 4
我们发现在算到最后时数字4又出现了,那么之后的数字又都会重复之前的顺序,这个循环中不包含1,那么数字11不是一个快乐数,发现了规律后就要考虑怎么用代码来实现,我们可以用 hashset 来记录所有出现过的数字,然后每出现一个新数字,在 hashset 中查找看是否存在,若不存在则加入表中,若存在则跳出循环,并且判断此数是否为1,若为1返回true,不为1返回false,代码如下:
解法一:
class solution { public: bool ishappy(int n) { unordered_set<int> st; while (n != 1) { int sum = 0; while (n) { sum += (n % 10) * (n % 10); n /= 10; } n = sum; if (st.count(n)) break; st.insert(n); } return n == 1; } };
其实这道题也可以不用 hashset 来做,我们并不需要太多的额外空间,关于非快乐数有个特点,循环的数字中必定会有4,这里就不做证明了,我也不会证明,就是利用这个性质,就可以不用set了,参见代码如下:
解法二:
class solution { public: bool ishappy(int n) { while (n != 1 && n != 4) { int sum = 0; while (n) { sum += (n % 10) * (n % 10); n /= 10; } n = sum; } return n == 1; } };
这道题还有一种快慢指针的解法,由热心网友喵团团提供,跟之前那道 linked list cycle 检测环的方法类似,不同的是这道题环一定存在,不过有的环不符合题意,只有最后 slow 停在了1的位置,才表明是一个快乐数。而且这里每次慢指针走一步,快指针走两步,不是简单的指向next,而是要调用子函数计算各位上数字的平方和,当快慢指针相等时,跳出循环,并且判断慢指针是否为1即可,参见代码如下:
解法三:
class solution { public: bool ishappy(int n) { int slow = n, fast = n; while (true) { slow = findnext(slow); fast = findnext(fast); fast = findnext(fast); if (slow == fast) break; } return slow == 1; } int findnext(int n) { int res = 0; while (n > 0) { res += (n % 10) * (n % 10); n /= 10; } return res; } };
类似题目:
linked list cycle
参考资料:
https://leetcode.com/problems/happy-number/discuss/56913/beat-90-fast-easy-understand-java-solution-with-brief-explanation
https://leetcode.com/problems/happy-number/discuss/56917/my-solution-in-c(-o(1)-space-and-no-magic-math-property-involved-)
到此这篇关于c++实现leetcode(202.快乐数)的文章就介绍到这了,更多相关c++实现快乐数内容请搜索<计算机技术网(www.ctvol.com)!!>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<计算机技术网(www.ctvol.com)!!>!
需要了解更多c/c++开发分享C++实现LeetCode(202.快乐数),都可以关注C/C++技术分享栏目—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/680103.html