Happy Number
描述: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
Outout: true
Explantation:
1 * 1 + 9 * 9 = 82
8 * 8 + 2 * 2 = 68
6 * 6 + 8 * 8 = 100
1 * 1 + 0 * 0 + 0 * 0 = 1
给出函数方法:
bool IsHappy(int n);
01 普通方法
思路:
1.先分离出每个每个数字的位数, 并返回每个数字的平方和
2.创建一个数组来存放当前数字,如果当前数字没有在数组里就继续执行, 如果在里面的话,就判断当前数字是否等于1, 如果是的耍就返回true, 不等于1的话就返回false;
代码如下:
返回下一个数字
int NextNumber(int n)
{
// 返回一个数的各个位上数值的平方和
int r = 0;
while (n != 0)
{
int d = n % 10; // 取出最后一位
n /= 10; // n为原来的十分之一
r += d * d; // 返回当前这一位的平方后的结果
}
return r; // 返回所有数字的平方和
}
当前数字是否以及存在
bool Contains(int* History, int Size, int n)
{
// 检查当前的这个数是否已经存在
for (int i = 0; i < Size; i++)
{
if (History[i] == n) // 判断当前数字是否在历史记录的数组里
{
return true;
}
}
return false;
}
是否为快乐数
bool IsHappy1(int n)
{
// History[1000]的设定是 一个数的一个位上的数值的平方最大为81(9 * 9 = 81)
//10位数的话最大也有810
int History[1000];
int Size = 0;
while (!Contains(History, Size, n))
{
// 不在History数组中就添加进去
History[Size] = n;
Size++;
n = NextNumber(n);
}
return n == 1;
}
02 优化方法
将上面的 bool IsHappy1(int n) 方法修改为为下面的代码:
bool IsHappy2(int n)
{
int Slow = n;
int Fast = n;
do
{
// 使用龟兔赛跑原理, 乌龟走的慢,走一格. 兔子走的快, 走两格.
// 兔子有可能饶了一圈超越乌龟, 和乌龟相遇就表示确实是一个圈
// 抽象为:双指针指向同一个值,然后跳出循环.
Slow = NextNumber(Slow);
Fast = NextNumber(Fast);
Fast = NextNumber(Fast);
// Fast = NextNumber(NextNumber(Fast));
} while (Slow != Fast);
return Fast == 1;
完整源代码:
头文件:
#ifndef __HappyNumber_H__
#define __HappyNumber_H__
int NextNumber(int n);
bool Contains(int* History, int Size, int n);
bool IsHappy1(int n);
bool IsHappy2(int n);
#endif
源文件:
#include "02HappyNumber.h"
int NextNumber(int n)
{
// 返回一个数的各个位的平方和
int r = 0;
while (n != 0)
{
int d = n % 10;
n /= 10;
r += d * d;
}
return r;
}
bool Contains(int* History, int Size, int n)
{
// 检查当前的这个数是否已经存在
for (int i = 0; i < Size; i++)
{
if (History[i] == n)
{
return true;
}
}
return false;
}
bool IsHappy1(int n)
{
// History[1000]的设定是 一个数的一个位上的数值的平方最大为91 10位数的话最大也有910
int History[1000];
int Size = 0;
while (!Contains(History, Size, n))
{
// 不在History数组中就添加进去
History[Size] = n;
Size++;
n = NextNumber(n);
}
return n == 1;
}
bool IsHappy2(int n)
{
int Slow = n;
int Fast = n;
do
{
// 使用龟兔赛跑原理, 乌龟走的慢,走一格. 兔子走的快, 走两格.
// 兔子有可能饶了一圈超越乌龟, 和乌龟相遇就表示确实是一个圈
// 抽象为:双指针指向同一个值,然后跳出循环.
Slow = NextNumber(Slow);
Fast = NextNumber(Fast);
Fast = NextNumber(Fast);
// fast = NextNumber(NextNumber(fast));
} while (Slow != Fast);
return Fast == 1;
}
测试文件:
#include <iostream>
#include <stdio.h>
#include "02HappyNumber.h"
using namespace std;
int main(int argc, char* argv[] )
{
int Number = 20;
bool Result = IsHappy1(Number);
cout << "普通方法:" << Result << endl;
Result = IsHappy2(Number);
cout << "优化方法:" << Result << endl;
Number = 19;
Result = IsHappy1(Number);
cout << "普通方法:" << Result << endl;
Result = IsHappy2(Number);
cout << "优化方法:" << Result << endl;
}