前言
之前小六六一直觉得自己的算法比较菜,算是一个短板吧,以前刷题也还真是三天打鱼,两天晒网,刷几天,然后就慢慢的不坚持了,所以这次,借助平台的活动,打算慢慢的开始开刷,并且自己还会给刷的题总结下,谈谈自己的一些思考,和自己的思路等等,希望对小伙伴能有所帮助吧,也可以借此机会把自己短板补一补,希望自己能坚持下去呀
链表的合集
题目
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。 如果这个过程 结果为 1,那么这个数就是快乐数。 如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
示例 1:
输入: n = 19 输出: true 解释: 12 + 92 = 82 82 + 22 = 68 62 + 82 = 100 12 + 02 + 02 = 1
示例 2:
输入: n = 2 输出: false
题解
这道题目看上去貌似一道数学问题,其实并不是!
题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!,那其实很简单,我们把每一次计算的结果放到一个set中,如果发现重复的,那么这个一定不是快乐数,否则我们就直接一直循环下去
代码
public boolean isHappy(int n) { Set<Integer> set = new HashSet<>(); while (n > 1 && !set.contains(n)) { set.add(n); n= next(n); } return n==1; } private int next(int n) { int sum=0; while (n>0){ int temp= n%10; sum+=temp*temp; n=n/10; } return sum; }
双指针法
一般来说,像这种类型的我们都可以把每个节点获得的值认为是一个节点,把这些节点全部连起来就是一个链表,那么这题就变成了 判断一个链接是否有相同的节点,也就是判断一个链表是否有环了
我们不是只跟踪链表中的一个值,而是跟踪两个值,称为快跑者和慢跑者。在算法的每一步中,慢速在链表中前进 1 个节点,快跑者前进 2 个节点(对 getNext(n) 函数的嵌套调用)。
如果 n 是一个快乐数,即没有循环,那么快跑者最终会比慢跑者先到达数字 1。
如果 n 不是一个快乐的数字,那么最终快跑者和慢跑者将在同一个数字上相遇。
class Solution { public int getNext(int n) { int totalSum = 0; while (n > 0) { int d = n % 10; n = n / 10; totalSum += d * d; } return totalSum; } public boolean isHappy(int n) { int slowRunner = n; int fastRunner = getNext(n); while (fastRunner != 1 && slowRunner != fastRunner) { slowRunner = getNext(slowRunner); fastRunner = getNext(getNext(fastRunner)); } return fastRunner == 1; } }
我们就可以把第一个节点当成是慢指针(走一步),第二个节点当初快指针(走二步),然后他们依次往下走,只要快指针不等于慢指针,或者是快指针到达1,就是我们的退出条件
结束
今天的刷题就到了,我是小六六,三天打鱼,两天晒网!