题目描述:
写一个算法来判断一个数是不是"快乐数"。
一个数是不是快乐是这么定义的:对于一个正整数,每一次将该数替换为他每个位置上的数字的平方和,然后重复这个过程直到这个数变为1,或是无限循环但始终变不到1。如果可以变为1,那么这个数就是快乐数。
样例:
19 就是一个快乐数。
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
解题思路:
一个点,如果一个数不是一个快乐数,最后必定形成一个循环的数字队列,陷入一个死循环。所以判断的标准的是,替换得到的数字是否在原来的数字队列中。
代码(naive版,我的):
class Solution { public: /** * @param n: An integer * @return: true if this is a happy number or false */ bool isHappy(int n) { // write your code here int flag = n, last; map<int, int> resultArray; while (true) { last = getHappyNumber(flag); if (1 == last) return true; if (resultArray.end() == resultArray.find(last)) resultArray.insert(resultArray.begin(), std::pair<int, int>(last, last)); else break; flag = last; } return false; } int getHappyNumber(int k) { int remainder, consult, sum; remainder = k; consult = sum = 0; while (0 != remainder) { consult = remainder % 10; sum += consult * consult; remainder = remainder / 10; } return sum; } };
九章解法:
class Solution { public: /** * @param n an integer * @return true if this is a happy number or false */ bool isHappy(int n) { // Write your code here if (n < 1) return false; if (n == 1) return true; unordered_set<int> showedNums; showedNums.insert(n); while (true) { int s = 0; while (n) { s += (n % 10) * (n % 10); n = n / 10; } if (s == 1) return true; else if (showedNums.find(s) != showedNums.end()) return false; n = s; showedNums.insert(s); } } };
这里就C++容器map的insert方法做一些讲解,主要是因为遇到了一个坑:
map支持三种插入方式:
single element (1) | pair<iterator,bool> insert (const value_type& val); |
---|---|
with hint (2) | iterator insert (iterator position, const value_type& val); |
range (3) | template <class InputIterator> void insert (InputIterator first, InputIterator last); |
首先这里的value_type并不是一个简单的类型,是std::pair类型
Member type
value_type
is the type of the elements in the container, defined in
map
as
pair<const key_type,mapped_type>
(see
map member types
).
在使用时注意这一点就行了