leetcode刷题记录-202. Happy Number

leetcode刷题记录-202. Happy Number

1.题目要求

  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.
  Note:
  You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively.
  Example: 19 is a happy number
       1^2 + 9^2 = 82
       8^2 + 2^2 = 68
       6^2 + 8^2 = 100
       1^2 + 0^2 + 0^2 = 1
  


2.问题分析

  给定一个正整数,循环计算它的每一位的平方和,如果结果为1说明它是一个”happy number”返回true,如果没有出现1就返回false。
  关键点
   a.由于正整数的位数不确定,因此需要先统计它有多少位,再求累加平方和
   b.循环计算的过程中,如何判断它不是一个“happy number”


3.解题思路

  • 思路一
      一开始的想法是:首先计算初始的平方和,然后一直循环求当前的平方和,如果循环的过程中出现了平方和为1,那么就返回true,如果一直循环到当前平方和与初始平方和相等,就返回false。
      这样的结果只能满足极个别的情况,主要是自己没有考虑周全。循环过程中确实会和之前的平方和有重复的情况,这就是一个循环,但是这个重复的值不一定就是初始值。所以这种方法有局限性。
  • 思路二
      参考别人的代码实现思路,单独写一个函数用于计算平方和。然后每次循环过程中分别计算两个值,一个值遍历速度要快些,另外一个值则逐个遍历。
     因为无论是不是happy number,这样计算肯定会有重复的值出现,这个时候就完成了一个大循环。整个过程可以理解成两个人在绕一个大圈跑,一个人的速度比较快,另外一个人速度比较慢,那么速度快的那个人迟早会和速度慢的人相遇。相遇的那个值就是整个大循环的起点,如果这个点的值是1,说明是happy number,否则就不是。

4.代码实现

  • 思路一
 bool isHappy(int n) 
    {
        int n_temp = n;
        int i, sum, sum_cur;
        sum = sum_cur = 0;
        vector <int> digits;
        while (n_temp != 0)//
        {
            digits.push_back(n_temp % 10);
            n_temp /= 10;
        }
        for (i = 0; i < digits.size(); i++)
        {
            sum += digits[i] * digits[i];
        }
        if (sum == 1)
            return true;

        sum_cur = sum;
        do
        {
            digits.clear();

            n_temp = sum_cur;
            while (n_temp != 0)
            {
                digits.push_back(n_temp % 10);//得到每一位的数字
                n_temp /= 10;       
            }

            //求平方和
            sum_cur = 0;
            for (i = 0; i < digits.size(); i++)
            {
                sum_cur += digits[i] * digits[i];
            }
            if (sum_cur == 1)
                return true;

        } while (sum != sum_cur);

        return false;
    }

以上代码只能通过极少部分示例,比如输入是3就会无限循环停不下来。。。。。

  • 思路二
//统计数字的每一位的平方和
    int getSum(int n)
    {
        int i,output=0;
        vector <int> digits;
        while (n)
        {
            digits.push_back(n % 10);
            n /= 10;
        }
        for (i = 0; i < digits.size(); i++)
        {
            output += digits[i] * digits[i];
        }
        return output;
    }

    bool isHappy(int n)
    {
        int n_temp = n;
        int i, sum_fast, sum_slow;
        sum_fast= sum_slow=n;
        while ((sum_fast != 1) && (sum_slow != 1))
        {
            sum_slow = getSum(sum_slow);
            sum_fast = getSum(sum_fast);
            sum_fast = getSum(sum_fast);

            if ((sum_fast == sum_slow) && (sum_slow != 1))
            {
                return false;
            }
        }

        return true;
    }
注:求数字的平方和的两种方式:

a.用”/”和”%”运算符求得每一位的数字后计算

int getSum(int n)
{
    int i,output,temp;
    output=0;
    vector <int> digits;
    while (n)
    {
        temp=n % 10;
        output+=temp*temp;
        n /= 10;
    }
    return output;
}

b.先将数字转换成字符串,然后计算,需要包含sstream头文件

int getSum(int n)
{
    int i,temp,count = 0;
    string number;
    stringstream ss;
    ss << n;
    ss >> number;
    for (i = 0; i < number.length(); i++)
    {
        temp = number[i] - '0';
        count += temp*temp;
    }

    return count;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值