双指针问题—— 快乐数
今天的题比较有意思,它相当于是从别的问题中进行迁移的问题,和之前的判断有环链表类似,需要借助到,快慢指针的帮助,接下来让我们来了解一下吧
😏本文由爱吃苹果的清梦,友情提供🐼
题目描述
算法解析
暴力解法
可以将本题当作一道简单的模拟题,然后模拟这其中的过程,只不过就是这样时间复杂度高。具体实践起来就是,预先设定一个最大计算次数,如果超过计算次数的话,就要跳出进行检查,它当前停留的循环数字是不是1.当然这样的方法并不是很严谨。
代码实现
class Solution {
public:
int change(char s_char)
{
return s_char -'0';
}
bool isHappy(int n) {
int cal = 100;
string tem = to_string(n);
int ret = 0;
while(cal--)
{
int sum = 0;
for(int i = 0;i < tem.size();i++)
{
int s_num = change(tem[i]);
sum += s_num * s_num;
}
if(sum == 1) return true;
ret = sum;
tem = to_string(ret);
}
if(ret== 1) return true;
return false;
}
};//这个方法倒是有一定的取巧成分,是题目样例卡的不严,能这样做
方法二 双指针算法
我们纵观整个题,他描述的流程,我们可以用图来表示一二:
相信通过这张图,就显而易见了,这不就是判断带环链表的题目,只不过是换了个模样罢了,那我们就心中了然,所以这道题的基本思路就是:设定两个指针,一个指向当前变换,另一个比当前的变化快一步,当他们相遇的时候我们判断环中节点到底是1,还是还是其他,对题目进行求解
代码实现
class Solution {
public:
int get(string ret)
{
int sum = 0;
for(int i = 0;i < ret.size();i++)
{
int ret1 = ret[i] - '0';
sum += ret1 * ret1;
}
return sum;
}
bool isHappy(int n) {
//因为是对应的对快慢指针进行重置,所以一开始都要对n进行,一两步操作
int slow = get(to_string(n));
int fast = get(to_string(n));
fast = get(to_string(fast));
while(slow != fast)
{
slow = get(to_string(slow));
fast = get(to_string(fast));
fast = get(to_string(fast));
//cout << fast << endl;
}
if(slow == 1) return true;
return false;
}
};
后记
通过这道题,对于带环链表又加以复习,这也是两道题的一个掺杂,对于本题,卡住我的点主要包含:在快慢指针时候,并没有对指针进行初始化处理。