快慢指针
顾名思义,快慢指针指的是一个快指针和慢指针,快指针一次走两步,慢指针一次走一步,(若不以这个速度又会有什么新的应用呢,待发现),那就先看看快慢指针的应用(待补充):
可以判断一个链表是否成环:
如果链表成环,那快慢指针就会向是两个速度不同的人在田径场(成环)上一起跑步,总有一个时间段两人会相遇,也就是在链表中,快慢指针会指向同一个位置,这样就可以判断该链表有一个环结构。
如不成环,则会出现快指针指向空。
如下列图示:
有机会我再做成gif图
我们的标题是快慢指针再leetcode题目里的应用,献上题目:
那这个题看着和链表没有半毛钱关系啊?
在仔细阅读题目之后,我们可以了解到无论这个数是不是快乐数,按照这种算法肯定是会陷入循环的,快乐数无限循环 1 , 非快乐数就不能快乐的循环 1 了, 他们会像链表那样,在某些数之间无限循环,这些数就像组成了一个环。还是举个例子:例如5:
5 → 25 → 29 → 83 → 73 → 58 → 89 → 145 → 42 → 20 → 4 → 16 → 37 → 58 → 89 →…
可以看到从 58 到 37 这些数字之间形成了一个闭环,所以如果
再来个快乐数:例如19:
19 → 82 → 68 → 100 → 1 → 1 → …
再非快乐数可以看到从 58 到 37 这些数字之间形成了一个闭环,而在快乐数中,则形成了无限的 1 , 所以在用快慢指针是, 我们可以设立一个死循环,只有快指针和慢指针相等时才可以推出,然后判断一下 快慢指针的值 若是 1, 则快乐,不为1,则不快乐
import math
class Solution(object):
def isHappy(self, n):
"""
:type n: int
:rtype: bool
"""
def wei_cal(n):
sums = 0
i = 1
wei = [] # 记录所有位数,首位是最高位
while True:
if pow(10, i-1) <= n < pow(10, i):
break
tmp = n % pow(10, i) # 计算第 i 位的值(低位开始)
# wei.append(int(tmp/pow(10, i - 1)))
we = int(tmp/pow(10, i - 1))
sums += we * we
i += 1
# wei.append(int(n/pow(10, i - 1)))
we = int(n/pow(10, i - 1))
sums += we * we
return sums
# def judge(n):
# result = 0
# res = set()
# wei = wei_cal(n)
# while True:
# for i in wei:
# result += pow(i, 2)
# if result in res:
# return False
# if result == 1:
# return True
# res.add(result)
# wei = wei_cal(result)
# result = 0
def judge(n):
slow = n
fast = wei_cal(n)
while slow != fast:
slow = wei_cal(slow)
fast = wei_cal(fast)
fast = wei_cal(fast)
return slow == 1
return judge(n)
```