【第四周打卡完成✔】
- 没有按照上周的复习计划进行
- 还是得每天做题才能保持题感呐
- 这周见识了很多新的题型:模板题、排序等等
- 新计划就是保持每天刷题 刷完一轮之后再回过来复习第二轮
#142.环形链表II【双指针】
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
fast,slow = head,head
while True:
if not (fast and fast.next):return
fast,slow = fast.next.next,slow.next
if fast == slow:break
fast = head
while fast!= slow:
fast,slow = fast.next,slow.next
return fast
#146.LRU缓存【双向链表】
class Node:
_slots_ = 'prev','next','key','value'
def __init__(self, key = 0,value = 0):
self.key = key
self.value = value
class LRUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.dummy = Node()
self.dummy.prev = self.dummy
self.dummy.next = self.dummy
self.key_to_node = dict()
def get_node(self,key:int) -> Optional[Node]:
if key not in self.key_to_node:
return None
node = self.key_to_node[key]
self.remove(node)
self.push_front(node)
return node
def get(self, key: int) -> int:
node = self.get_node(key)
return node.value if node else -1
def put(self, key: int, value: int) -> None:
node = self.get_node(key)
if node:
node.value = value
return
self.key_to_node[key] = node = Node(key,value)
self.push_front(node)
if len(self.key_to_node) > self.capacity:
back_node = self.dummy.prev
del self.key_to_node[back_node.key]
self.remove(back_node)
def remove(self,x:Node) -> None:
x.prev.next = x.next
x.next.prev = x.prev
def push_front(self,x:Node) -> None:
x.prev = self.dummy
x.next = self.dummy.next
x.prev.next = x
x.next.prev = x
#148.排序链表【归并排序】⭐八大排序
class Solution:
def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if not head or not head.next:return head
slow,fast = head,head.next
while fast and fast.next:
fast,slow = fast.next.next,slow.next
mid,slow.next = slow.next,None
left,right = self.sortList(head),self.sortList(mid)
h = res = ListNode(0)
while left and right:
if left.val < right.val:h.next,left = left,left.next
else:h.next,right = right,right.next
h = h.next
h.next = left if left else right
return res.next
#152.乘积最大子数组【动态规划】
class Solution:
def maxProduct(self, nums: List[int]) -> int:
n = len(nums)
a = b = 1
ans = float('-inf')
for i in range(1,n+1):
temp = a
a = max(a*nums[i-1],b*nums[i-1],nums[i-1])
b = min(temp*nums[i-1],b*nums[i-1],nums[i-1])
ans = max(ans,a)
return ans
#155.最小栈【模板题】
class MinStack:
def __init__(self):
self.stack = []
self.min_stack = []
def push(self, x: int) -> None:
self.stack.append(x)
if not self.min_stack or x <= self.min_stack[-1]:
self.min_stack.append(x)
def pop(self) -> None:
if self.stack.pop() == self.min_stack[-1]:
self.min_stack.pop()
def top(self) -> int:
return self.stack[-1]
def getMin(self) -> int:
return self.min_stack[-1]
#160.相交链表【双指针】
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
A,B = headA,headB
while A != B:
A = A.next if A else headB
B = B.next if B else headA
return A
#169.多数元素【⭐】
class Solution:
def majorityElement(self, nums: List[int]) -> int:
major,count = 0,0
for n in nums:
if count == 0:
major = n
if n == major:
count = count + 1
else:
count = count - 1
return major
#198.打家劫舍【动态规划】
class Solution:
def rob(self, nums: List[int]) -> int:
if len(nums) == 0:return 0
dp = [0]*(len(nums)+1)
dp[0] = 0
dp[1] = nums[0]
for k in range(2,len(nums)+1):
dp[k] = max(dp[k-1],nums[k-1]+dp[k-2])
return dp[len(nums)]
#200.岛屿数量【广度优先搜索】
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
count = 0
for row in range(len(grid)):
for col in range(len(grid[0])):
if grid[row][col] == '1':
count += 1
grid[row][col] = '0'
land_positions = collections.deque()
land_positions.append([row,col])
while len(land_positions) > 0:
x,y = land_positions.popleft()
for new_x,new_y in [[x,y+1],[x,y-1],[x+1,y],[x-1,y]]:
if 0 <= new_x < len(grid) and 0 <= new_y < len(grid[0]) and grid[new_x][new_y] == '1':
grid[new_x][new_y] = '0'
land_positions.append([new_x,new_y])
return count
#206.反转链表【双指针】
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
cur,pre = head,None
while cur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
#207.课程表【拓扑排序】
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
indegrees = [0 for _ in range(numCourses)]
adjacency = [[] for _ in range(numCourses)]
queue = deque()
for cur,pre in prerequisites:
indegrees[cur] += 1
adjacency[pre].append(cur)
for i in range(len(indegrees)):
if not indegrees[i]:queue.append(i)
while queue:
pre = queue.popleft()
numCourses -= 1
for cur in adjacency[pre]:
indegrees[cur] -= 1
if not indegrees[cur]:queue.append(cur)
return not numCourses
#208.实现前缀树【模板题】
class Node:
def __init__(self):
self.children = collections.defaultdict(Node)
self.isword = False
class Trie:
def __init__(self):
self.root = Node()
def insert(self, word: str) -> None:
current = self.root
for w in word:
current = current.children[w]
current.isword = True
def search(self, word: str) -> bool:
current = self.root
for w in word:
current = current.children.get(w)
if current == None:
return False
return current.isword
def startsWith(self, prefix: str) -> bool:
current = self.root
for w in prefix:
current = current.children.get(w)
if current == None:
return False
return True
#215.数组中的第k个最大元素【快速排序】
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
def quick_select(nums,k):
pivot = random.choice(nums)
big,equal,small = [],[],[]
for num in nums:
if num > pivot:
big.append(num)
elif num < pivot:
small.append(num)
else:
equal.append(num)
if k <= len(big):
return quick_select(big,k)
if len(nums) - len(small) < k :
return quick_select(small,k-len(nums)+len(small))
return pivot
return quick_select(nums,k)
#221.最大正方形【动态规划】
class Solution:
def maximalSquare(self, matrix: List[List[str]]) -> int:
if not matrix:return 0
m = len(matrix)
n = len(matrix[0])
res = 0
dp = [[0]*(n+1) for _ in range(m+1)]
for i in range(1,m+1):
for j in range(1,n+1):
if (matrix[i-1][j-1] == '1'):
dp[i][j] = min(dp[i-1][j-1],dp[i-1][j],dp[i][j-1])+1
res = max(dp[i][j],res)
return res*res
#226.翻转二叉树【递归】
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:return
root.left,root.right = self.invertTree(root.right),self.invertTree(root.left)
return root
#234.回文链表【快慢指针+翻转+对比】
class Solution:
def isPalindrome(self, head: Optional[ListNode]) -> bool:
if not head or not head.next:return True
slow,fast = head,head
while fast and fast.next:
slow,fast = slow.next,fast.next.next
if fast:
slow = slow.next
prev,cur = None,slow
while cur:
tmp = cur.next
cur.next = prev
prev = cur
cur = tmp
p1,p2 = head,prev
while p1 and p2:
if p1.val != p2.val:
return False
p1 = p1.next
p2 = p2.next
return True