question:查找链表种是否存在循环,head代表头节点
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
法1,用哈希表来存储
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
hash={}
while head: //代表链表没有遍历完
if hash.get(head): //用get函数来获取字典中head对应的值,默认为NULL
return True
hash[head]=1 //将head作为键,值设为1
head=head.next
return False
法2,龟兔赛跑模型
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
slow,fast=head,head
while True:
if not(fast and fast.next):
return False
fast,slow=fast.next.next,slow.next //快走两步,慢走一步
if fast == slow:
return True
return False
注:这种算法之所以有效,是因为快指针每次移动两步,慢指针每次移动一步。如果链表中存在循环,快指针最终会追上慢指针,从而导致它们相遇。如果没有循环,快指针最终会走到链表的末尾。
这种算法的时间复杂度为 O(n),其中 n 是链表的长度。它具有很好的空间效率,因为只使用了常数级别的额外空间。这是一种常用于解决链表循环检测问题的经典算法。
变体:要求返回循环的入口位置
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
slow,fast=head,head
while True:
if not(fast and fast.next):
return False
fast,slow=fast.next.next,slow.next //快走两步,慢走一步
if fast == slow:
break
fast=head //这边要小心,一定要跳出上一个循环,否则会造成超时
while fast!=slow:
fast,slow=fast.next,slow.next
return fast
question:求众数,在一个无序数组中,找到出现频率>n/2的数
这里运用了对抗的思想,定义一个major和一个计数器,如果下一个数跟当前一样,则计数器+1,否则-1,当计数器为0时,major改变为当前所指向的数。
class Solution:
def majorityElement(self, nums: List[int]) -> int:
major,count=nums[0],1
for i in range(1,n):
if count == 0:
major=nums[i]
if nums[i] == major:
count+=1
else:
count-=1
return major
用栈来求解:(但是速度不如对抗式)
class Solution:
def majorityElement(self, nums: List[int]) -> int:
stack=[]
for n in nums:
if len(stack) == 0:
stack.append(n)
if stack[-1]!=n:
stack.pop(-1)
else:
stack.append(n)
return stack[-1]
**python3对于函数的缩进非常苛刻,需要注意缩进问题
此外对于数组,要注意范围,最后一个元素如R=n-1