LeetCode 202 Happy Number(开心数)(vector、unordered_set)
2016-01-19 10:51
507 查看
翻译
[code]写一个算法来决定一个数是否是“开心”的。 开心数是被如下步骤所定义的数: 从所有正整数开始,用其每个数字的平方和来替代这个数,不断重复这个过程直到最后的结果为1(此时它就停止了), 或者它在一个不包含1的周期内无限循环。 这些在这个过程中以1结尾的数就是开心数。 例如:19是开心数。
12+92=821^2 + 9^2 = 82
82+22=688^2 + 2^2 = 68
62+82=1006^2 + 8^2 = 100
12+02+02=11^2 + 0^2 + 0^2 = 1
原文
[code]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.
[code]Example: 19 is a happy number
12+92=821^2 + 9^2 = 82
82+22=688^2 + 2^2 = 68
62+82=1006^2 + 8^2 = 100
12+02+02=11^2 + 0^2 + 0^2 = 1
分析
我原以为这道题难点只是在于把那些那些数字包含的数都找出来,也就是说给出19找出1和9,后来发现还有一个难点……[code]int getSum(int num) { vector<int> digits; while (num > 9) { digits.push_back(num % 10); num = num / 10; } digits.push_back(num); int sum = 0; for (int i = 0; i < digits.size(); i++) { sum += digits[i] * digits[i]; } return sum; }
这里用vector来保存了每个数字,然后将其求平方和。下面是一个递归,多嵌套了一层,难度其实也不大,然而提交之后发现还是错了。
[code]bool isHappy(int n) { if (n == 1) return true; else return isHappy(getSum(n)); return false; }
反馈的结果是说2不能通过,试了试:
[code]2,4,16,27,58……最后又是4,16成了死循环了
喔喔,题意中确实提到了:
[code]或者它在一个不包含1的周期内无限循环
想了好久没有想到什么办法能够找出死循环的判断方法,于是只能去找规律了。发现对于:
[code]2,4,8,3,6,9,5
都会造成死循环,于是干脆加上一个判断条件,n等于这些数字时直接返回false。果然通过了……
代码
[code]class Solution { public: int getSum(int num) { vector<int> digits; while (num > 9) { digits.push_back(num % 10); num = num / 10; } digits.push_back(num); int sum = 0; for (int i = 0; i < digits.size(); i++) { sum += digits[i] * digits[i]; } return sum; } bool isHappy(int n) { if (n == 1) return true; else if (n != 7 && (2 <= n && n <= 9)) return false; else return isHappy(getSum(n)); return false; } };
进阶
不过我对这种解法还不太满意,因为虽然可以找规律,但毕竟要花蛮多的时间。去学习学习别人的解法吧……[code]bool isHappy(int n) { unordered_set<int> visited; while (n != 1) { if (visited.find(n) != visited.end()) return false; visited.insert(n); int sum = 0; while (n) { sum += ((n % 10)*(n % 10)); n /= 10; } n = sum; } return true; }
这个解法就是完美解决了死循环的问题,用unordered_set的find函数可以很快判断一个数字是否已经访问过了,如果是的话肯定直接false了。
后面的while循环部分则和我的大同小异了 。
相关文章推荐
- android 列表倒计时流畅的完美实现
- 百度云推送图文教程IOS
- 推荐几款实用的Android Studio 插件
- Android高效加载大图、多图解决方案,有效避免程序OOM
- 微信自定义菜单生成器
- Android测试环境配置
- Android性能优化典范
- android自带图片资源图标一览,android.R.drawable
- Android应用内打开QQ聊天框
- JavaScript开发原生App模式能否突出重围?
- iOS中NavigationBar设置
- android shape的使用
- IOS开发——Swift和Objective-C交互时的一些注意点
- unity3d 简单的xml文件读写操作
- iOS获取xcassets中LaunchImage图片
- iOS Code Signing(ios自学笔记)
- Android--AndroidManifest 中original-package标签
- android之android studio的NDK环境搭建
- Android Studio常用插件
- Android百度地图实现搜索和定位及自定义图标绘制并点击时弹出泡泡