序言
今天是情人节了诶各位~
你快乐吗?
我们来做一道快乐数看看吧
题目
题解
- 方法1:纯按题目定义计算,设定最大迭代次数k,若到达k还无法判断,则默认为非快乐数,时间复杂度O(n)
C++
class Solution {
public:
//int型n分解成字符串s
string devide(int n)
{
string s;
while(n)
{
s.push_back(n%10);
n/=10;
}
return s;
}
//快乐数判断
bool isHappy(int n) {
string s=devide(n);
int k=0;
//最大迭代次数k设定为100
while(k<100)
{
int sum=0;//sum记录各位的平方和
for(int i=0;i<s.size();i++)
{
sum+=s[i]*s[i];
}
//是快乐数,返回true
if(sum==1)
return true;
//不是快乐数,继续分解sum成字符串
else
{
s=devide(sum);
k++;
}
}
return false;
}
};
python
class Solution:
def isHappy(self, n: int) -> bool:
for k in range(100):
sum=0
# python里可以直接把n转成字符串
# i代表n中的每个字符
for i in str(n):
sum+=int(i)**2
if sum==1:
return True
else:
n=sum
return False
虽然通过了,但是这种做法还是有缺陷,因为有可能在第101次时判断n是快乐数
- 方法2:找规律,快乐数最后会收敛到1,而非快乐数会4 → 16 → 37 → 58 → 89 → 145 → 42 → 20 → 4循环,因此若n等于4时,则可判断其为非快乐数,时间复杂度O(n2)
C++
class Solution {
public:
//int型n分解成字符串s
string devide(int n)
{
string s;
while(n)
{
s.push_back(n%10);
n/=10;
}
return s;
}
//快乐数判断
bool isHappy(int n) {
string s=devide(n);
while(1)
{
int sum=0;//sum记录各位的平方和
for(int i=0;i<s.size();i++)
{
sum+=s[i]*s[i];
}
//是快乐数,返回true
if(sum==1)
return true;
//不是快乐数,返回false
else if(sum==4)
return false;
//否则,进入下一次循环
else
s=devide(sum);
}
}
};
python
class Solution:
def isHappy(self, n: int) -> bool:
while(1):
sum=0
for i in str(n):
sum+=int(i)**2
if sum==1:
return True
elif sum==4:
return False
n=sum
这个速度比方法1快了1倍多
- 方法3:快慢指针判断循环,由于非快乐数是循环的,因此设定快慢指针,快指针一次走两步,慢指针一次走一步,如果相等且不为1,则一定是非快乐数,时间复杂度O(n2)
C++
class Solution {
public:
//n按位平方和相加
int calculate(int n)
{
int sum=0;
while(n)
{
int a=n%10;
sum+=a*a;
n/=10;
}
return sum;
}
//快乐数判断
bool isHappy(int n) {
int quick=n,slow=n;
do{
//慢指针一步
slow=calculate(slow);
//快指针两步
quick=calculate(quick);
quick=calculate(quick);
}while(slow!=quick);
//快慢指针相等
if(quick==1)
return true;
else
return false;
}
};
python
class Solution:
def isHappy(self, n: int) -> bool:
quick=slow=n
while True:
# 慢指针走一步
slow=sum([int(i)**2 for i in str(slow)])
# 快指针走两步
quick=sum([int(i)**2 for i in str(quick)])
quick=sum([int(i)**2 for i in str(quick)])
# 相等则跳出循环
if quick==slow:
break
# 慢指针=快指针
if quick==1:
return True
else:
return False
速度与方法2差不多