您的位置:首页 > 移动开发

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循环部分则和我的大同小异了 。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: