136.只出现一次的数字
入门必做题之一;解法二为最优解。(解法一虽然不符合常数空间的要求,但是作为最容易想到的解法,这里也给出来了)
解法一:哈希表
使用哈希表存储数字出现的次数,然后遍历哈希表返回只出现一次的数字。
以下两个代码完全相同,不过第二个使用了python
内置的一个高级dict()
类来简化代码。
代码一:
class Solution:
def singleNumber(self, nums: List[int]) -> int:
Hash = dict()
for num in nums:
if num not in Hash:
Hash[num] = 1
else:
Hash[num] += 1
for n in Hash:
if Hash[n] == 1:
return n
时间复杂度O(n)
,空间复杂度O(n)
。
代码二:
class Solution:
def singleNumber(self, nums: List[int]) -> int:
Hash = collections.defaultdict(int)#高级的dict()类
for num in nums:
Hash[num] += 1
for n in Hash:
if Hash[n] == 1:
return n
时间复杂度O(n)
,空间复杂度O(n)
。
解法二:位运算
使用到的位运算小知识:x^x=0
; x^0=x
。
class Solution:
def singleNumber(self, nums: List[int]) -> int:
ans = 0
for num in nums:
ans ^= num
return ans
时间复杂度O(n)
,空间复杂度O(1)
。
141.环形链表
经典的龟兔赛跑题(快慢指针)。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
# 快慢指针的经典题目,如果有环的话,快指针一定会追上慢指针。
# 如果没有环的话,快指针会先到达链表最后然后退出。
slow, fast = head, head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if slow == fast:
return True
return False
时间复杂度O(n)
,空间复杂度O(1)
。
142.环形链表Ⅱ
本题与287.寻找重复数
解题思路一模一样,只不过一个是数组的下标与内容的映射,一个是链表的.next
,其中287题
在另外一篇博客里面有详细的数学证明,参考以下链接:
287.寻找重复数
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
fast, slow = head, head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
fast = head
# 以下代码改为注释掉的四行是不等价的
while fast != slow:
fast = fast.next
slow = slow.next
return slow
# # 下面代码不对的原因是:当链表本身只有一个环的时候,
# 返回的slow并不一定是头结点head,可能是环中的其他节点。
# while True:
# fast = fast.next
# slow = slow.next
# if fast = slow:
# return slow
return None
时间复杂度O(n)
,空间复杂度O(1)
.