第七天:
二叉树的中后 层序遍历 对应leetcode 145 102 94题
二叉树专场:中后序遍历没啥问题,一个套路,递归就完事了:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def inorder(self, root, res):
if root == None:
return
self.inorder(root.left, res)
res.append(root.val)
self.inorder(root.right, res)
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root == None:
return []
res = []
self.inorder(root, res)
return res
建立一个数组,每次放一个数进去,而不需要return 这种递归也是合理的
层序遍历,因为要按照顺序输入,很容易让人想到一个队列,而你在队列中也要分开一层层的,一开始没有想到,后面看了答案就知道了,没必要分层,每次输出完一层,把整个临时队列重置了就行,然后再空队列里面放入新的节点接着输出,这是一个很精妙的做法(也许常见?)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if root == None:
return []
res = []
queue = [root]
while queue:
res.append([i.val for i in queue])
temp = []
for node in queue:
if node.left:
temp.append(node.left)
if node.right:
temp.append(node.right)
queue = temp
return res
第八天:
53 121 200
53 121 最大数组和 股票收益最大 两个分治题,这种分治题果然还是要常做常练才行,把大问题变成小问题,之后根据小问题来做,问题在于状态转移和那个dp矩阵,注意到一点是dp矩阵也可以是一维的,状态转移要灵活一点,到目前为止的值可以相加:
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
n = len(nums)
pre = 0
res = nums[0]
for i in range(n):
pre = max(nums[i], pre+nums[i])
res = max(pre, res)
return res
class Solution:
def maxProfit(self, prices: List[int]) -> int:
n = len(prices)
if n == 0: return 0
dp = [0] * n
minprice = prices[0]
for i in range(1, n):
minprice = min(minprice, prices[i])
dp[i] = max(dp[i-1], prices[i] - minprice)
return dp[n-1]
每次跟哪个数字比要注意
DPS BPS 深搜 广搜 概念复习了一下 然后其实挺简单的 ,搜 然后把搜过的标一下,后面再统计就行了:这题用深搜
class Solution:
def dfs(self, grid, i, j):
if i<0 or j<0 or i>=len(grid) or j>=len(grid[0]) or grid[i][j] != '1':
return
grid[i][j] = '0'
self.dfs(grid, i+1, j)
self.dfs(grid, i-1, j)
self.dfs(grid, i, j+1)
self.dfs(grid, i, j-1)
def numIslands(self, grid: List[List[str]]):
if not grid:return 0
anw = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == '1':
self.dfs(grid, i, j)
anw += 1
return anw
第九天:
110 104 98 二叉树专场:
看见二叉树什么的别怕,也就是个动态规划或者递归,关键是分解问题 大问题变小问题,还有假设已经解决了小问题了,二叉树就是分成左问题右问题罢了
平衡二叉树110其实就是左右两边算高度如何比较一下:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
self.res = True
def helper(root):
if not root:
return 0
left = helper(root.left) + 1
right = helper(root.right) + 1
if abs(right - left) > 1:
self.res = False
return max(left, right)
helper(root)
return self.res
104二叉树最大深度 上一题的简单版 就是递归,分解成左右两个深度,假设他已经解决了,如何算深度就行:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root: return 0
left = self.maxDepth(root.left)
right = self.maxDepth(root.right)
return max(left, right)+1
98 二叉搜索树 二叉树其实都差不多,也就是遍历每一个节点,递归或者什么的 左右两个都遍历,假设已经解决了,然后做一些操作,
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
def anw(root, min, max):
if not root: return True
if(min != None and root.val <= min.val): return False
if(max != None and root.val >= max.val): return False
return anw(root.left, min, root) and anw(root.right, root, max)
return anw(root, None, None)
这个就是左右放进去然后比大小就完事了
第十天:
103 146
103 锯齿遍历 跟94层序遍历是一样的,一样的队列一样的操作,加一个标记,奇数正着输出偶数反着输出就成:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
if not root: return []
queue = [root]
anw = []
flag = 0
while queue:
temp = []
if flag % 2 == 0:
anw.append([i.val for i in queue])
flag += 1
elif flag % 2 == 1:
a = [i.val for i in queue]
a = a[::-1]
anw.append(a)
flag += 1
for i in queue:
if i.left:
temp.append(i.left)
if i.right:
temp.append(i.right)
queue = temp
return anw
146 LRU缓存,新题型,做一个模型class 实现方法,主要涉及到一些字典的操作,主要收获1 python里面的字典天然有序,后放的会放到后面,然后你可以通过先删掉然后再原样放进去,把它调到最后。还有就是python 有一个orderdict,有各种有序字典操作,有空可以了解一下:
class LRUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.d = dict()
def get(self, key: int) -> int:
if key in self.d:
value = self.d[key]
self.d.pop(key)
self.d[key] = value
return value
else:
return -1
def put(self, key: int, value: int) -> None:
if len(self.d) == self.capacity and key not in self.d:
for k in self.d.keys():
self.d.pop(k)
self.d[key] = value
break
else:
if key not in self.d:
self.d[key] = value
else:
self.d.pop(key)
self.d[key] = value
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)