寻找快乐数
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
各位数字上的平方之和再相加,最后如果得到了数字1,则这个数字就是快乐数,否则就不是。
快乐数具有以下的特性:
数字有没有可能会无限大且没有循环?
答: 不可能。
例如数字: 2147483648,把他每一位拆分计算后:它肯定就会变成一个三位的数字,因此它不可能无限大下去,它一定会有一个循环或者最后结果为1.
方法一:
利用 哈希集和 统计计算的每一次的结果,如果陷入了循环,则哈希集合将显示为已经存在,因此此时就可以退出循环,即最后的结果为false;如果结果为1,则结束循环,返回true。
class Solution {
public:int getnum(int n){int sum=0;while (n){sum+=(n%10) * (n%10);n/=10;}return sum;}bool isHappy(int n) {unordered_set s;while (n!=1 && !s.count(n)){s.insert(n);n=getnum(n);}return n==1;}
};
方法二:
利用快慢指针,又叫龟兔赛跑法。

class Solution {
public:int getnum(int n){int sum=0;while (n){sum+=(n%10) * (n%10);n/=10;}return sum;}bool isHappy(int n) {int slow=n;int fast=getnum(n);while (fast!=1 && fast!=slow){slow=getnum(slow);fast=getnum(getnum(fast));}return fast==1;}
};
环形链表
给你一个链表的头节点 head ,判断链表中是否有环。

对于循环链表,我们也采用这种循环检测的算法,即双指针或者哈希集合的方式:
首先来哈希集和:
class Solution {
public:bool hasCycle(ListNode *head) {unordered_set s;ListNode* p=head;while (p!=nullptr && !s.count(p)){s.insert(p);p=p->next;}return p!=nullptr;}
};
方法二:
快慢指针法:
class Solution {
public:bool hasCycle(ListNode *head) {if (!head || !head->next){return false;}ListNode* pfast=head->next;ListNode* pslow=head;while (pfast!=nullptr && pfast!=pslow){pslow=pslow->next;pfast=pfast->next;if (pfast!=nullptr){pfast=pfast->next;}}return pfast!=nullptr;}
};
我们利用双指针或者哈希集合能够很轻松的检测到是否有循环发生,以及何时退出循环,但是我们该如何返回刚进入循环时的第一个节点呢?
使用哈希集和可以很轻松的解决这个问题
我们如果使用双指针,该如何获得链表得入口节点呢??
这还不简单,当快指针等于慢指针得时候,定义一个临时得节点,然后让他走到快指针的位置,返回这个位置,不就是这个入口节点吗?
大家仔细想一想,快慢指针的相遇不一定是在入口节点发生的,有可能在循环的圈内,因此返回快指针的位置是完全错误的。。
我们首先来整理一下思路:

a=c+(n−1)(b+c)a=c+(n−1)(b+ c 这个公式是什么意思??
我们把它翻译成人话:
从相遇点到入环点的距离加上 n−1 圈的环长,恰好等于从链表头部到入环点的距离。
因此当一个临时指针和慢指针同时每次走一步,slow从相遇点开始走,pTemp从链表头开始走,最后他们会同时在入口节点处相遇:
class Solution {
public:ListNode *detectCycle(ListNode *head) {ListNode* pfast=head;ListNode* pslow=head;while (pfast!=nullptr){pslow=pslow->next;if (pfast->next==nullptr){return nullptr;}pfast=pfast->next->next;if (pfast==pslow){ListNode* pTemp=head;while (pTemp!=pslow){pTemp=pTemp->next;pslow=pslow->next;}return pTemp;}}return nullptr;}
};
上一篇:Java---Map双列集合
下一篇:数据库实验三 数据查询一