0
点赞
收藏
分享

微信扫一扫

leetcode 202. 快乐数 思考分析(哈希集合与双指针解)

1、题目

编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。
leetcode 202. 快乐数 思考分析(哈希集合与双指针解)_链表

2、思考分析

对一个数不断进行get_sum操作,那么最终可能的结果有两种可能:
1、得到1
2、计算的数陷入某种循环,然后会有重复的数出现
如果得到1,直接返回true;
如果检测到重复数出现就返回false;
否则记录出现的数,并在while循环中对n进行更新。

int get_sum(int n)
{
int sum=0;
while(n!=0)
{
sum+=(n%10)*(n%10);
n = n/10;
}
return sum;
}

3、哈希法解

class Solution {
public:
int get_sum(int n)
{
int sum=0;
while(n!=0)
{
sum+=(n%10)*(n%10);
n = n/10;
}
return sum;
}
bool isHappy(int n) {
int sum=0;
//sum,sum出现的频次
unordered_set<int> set;
while(1)
{
sum=get_sum(n);
if(sum ==1) return true;
//如果某个数重复出现,那么我们认为此时陷入了循环,则这个数不是快乐数
else if(set.find(sum)!=set.end())
{
return false;
}
set.insert(sum);
n=sum;
}
}
};

4、双指针解

leetcode 202. 快乐数 思考分析(哈希集合与双指针解)_数据结构_02
我们得到的结果序列是一个隐式的链表。
隐式意味着我们没有实际的链表节点和指针,但数据仍然形成链表结构。
于是这个问题可以转换为检测一个链表是否有环。
这个问题可以使用快慢指针法来解决。我们不是只跟踪链表中的一个值,而是跟踪两个值,称为快跑者和慢跑者。在算法的每一步中,慢速在链表中前进 1 个节点,快跑者前进 2 个节点。
前进一次调用一次计算函数,前进两次调用两次计算函数。

class Solution {
public:
int get_next(int n)
{
int sum=0;
while(n!=0)
{
sum+=(n%10)*(n%10);
n = n/10;
}
return sum;
}
bool isHappy(int n) {
int sum=0;
int slow_runner = n;
int fast_runner = get_next(n);
while( fast_runner != 1 && slow_runner != fast_runner)
{
//更新slow_runner,slow_runner每次前进一步
slow_runner = get_next(slow_runner);
//更新fast_runner,fast_runner每次前进二步,所以调用两次getnext函数
fast_runner = get_next(get_next(fast_runner));
}
if(fast_runner == 1) return true;
return false;
}
};


举报

相关推荐

0 条评论