题目:
第一天:剑指 Offer 34. 二叉树中和为某一值的路径
第二天:剑指 Offer 36. 二叉搜索树与双向链表
第三天:11. 盛最多水的容器
第四天:704. 二分查找 27. 移除元素
第五天:209. 长度最小的子数组
第六天:59. 螺旋矩阵 II
第七天:203. 移除链表元素
收获:
1.在要返回多个列表组成的列表时要先pop()列表中的元素:
class Solution:
def pathSum(self, root: TreeNode, target: int) -> List[List[int]]:
#创建两个list(),res用来存储最终的答案,path用来存放中途的数据
res, path = [], []
#recur函数用来进行dfs
def recur(root, target):
if not root: return
path.append(root.val)
target -= root.val
if target == 0 and not root.left and not root.right:
#将整个path都append给res
res.append(list(path))
recur(root.left, target)
recur(root.right, target)
#将已经满足条件的储存在path中的数pop()寻找下一个满足的list
path.pop()
recur(root, target)
return res
2.还存在一些问题,逻辑看懂了,在代码上实现有点没看懂
核心:self.pre.right, cur.left = cur, self.pre,把前一个结点的后结点赋值为当前结点,当前结点的前结点设为前一个结点
class Solution:
def treeToDoublyList(self, root: 'Node') -> 'Node':
#二叉树中right表示下一个结点, left表示上一个结点
#cur表示正在访问的结点,pre表示上一个结点
def dfs(cur):
if not cur: return
#dfs左子树
dfs(cur.left)
#pre不为空修改双向结点
if self.pre:
self.pre.right, cur.left = cur, self.pre
#访问第一个结点
else:
self.head = cur
self.pre = cur
dfs(cur.right)
if not root: return
self.pre = None
dfs(root)
#修改引用
self.head.left, self.pre.right = self.pre, self.head
return self.head
3.双指针用法,在边界条件左指针,取值并右移,右指针同理(本题只能max(min(边界)×宽度))
class Solution:
def maxArea(self, height: List[int]) -> int:
#双指针
i, j, res = 0, len(height) - 1, 0
while i < j:
#右边更高,左指针右移
#左边更高,右指针左移
if height[i] < height[j]:
res = max(res, height[i] * (j - i))
i += 1
else:
res = max(res, height[j] * (j - i))
j -= 1
return res
4.标准二分查找, 快慢指针
疑问点:为什么返回的数组长度就变成了对应长度的数组值
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
class Solution:
def search(self, nums: List[int], target: int) -> int:
n = len(nums)
left, right = 0, n - 1
while left <= right:
middle = (left + right) // 2
if target < nums[middle]:
right = middle - 1
elif target > nums[middle]:
left = middle + 1
else:
return middle
return -1
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
slow, fast = 0, 0
n = len(nums)
while fast < n:
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow
5.滑动窗口机制,先从两个指针快指针找到满足条件的值后,慢指针移动一位,快指针重新找到新的满足条件的值(在慢指针前移一位时,从sum中减去nums[start])直到慢指针到n的位置(初始化ans = n+1)。return 0 if ans == n + 1 else ans等价于if xxx: return 0 else: return ans
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
if not nums: return 0
start, end, sum = 0, 0, 0
n = len(nums)
ans = n + 1
while end < n:
sum += nums[end]
while sum >= target:
ans = min(ans, end - start + 1)
sum -= nums[start] #start往后移动一位,此时sum也要减去已经加过的nums[start]值
start += 1
end += 1
return 0 if ans == n + 1 else ans
6.初始化二位数组:matrix = [[0 for _ in range(n)] for _ in range(n)],_只是一个占位符,用for是深拷贝。跑完整个循环后,分析不满足条件的点,原因可能是1时,本身就不满足while循环。
class Solution:
def generateMatrix(self, n: int) -> List:
#初始化正方形矩阵,_只是一个占位符,用for是深拷贝
matrix = [[0 for _ in range(n)] for _ in range(n)]
left, right, high, low = 0, n - 1, 0, n - 1
number = 1
while high < low and left < right:
#从左到右
for i in range(left, right):
matrix[high][i] = number
number += 1
#从上到下
for i in range(high, low):
matrix[i][right] = number
number += 1
#从右到左,从right往left,差值为-1,right>left
for i in range(right, left, -1):
matrix[low][i] = number
number += 1
#从下到上,从low往high,差值为-1,low>high
for i in range(low, high, -1):
matrix[i][left] = number
number += 1
#循环一圈,缩小一圈
high += 1
right -= 1
low -= 1
left += 1
#当一共奇数圈时,给几何中心赋值,要在整个循坏外,当只有一个元素时用
if n % 2:
matrix[n // 2][n // 2] = number
return matrix
7.设立傻瓜头结点主要目的是考虑到如果要删除头结点,让本来的头结点变为傻瓜头结点的next结点,删除结点方式cur.next = cur.next.next
class Solution:
def removeElements(self, head: ListNode, val: int) -> ListNode:
#新建一个链表结构dummy_head,令dummy_head.next == head
#设立dummy_head是为了让head成为dummy_head.next,方便删除头结点
dummy_head = ListNode(next = head)
#cur和dummy_head指向相同的物理地址,一起变化
cur = dummy_head
while cur.next != None:
if cur.next.val == val:
cur.next = cur.next.next
else:
cur = cur.next
#头结点为0,如果return dummy_head的话,会多一个0的值
return dummy_head.next
另外:感谢Carl,给了很多思路和参考(包括做题顺序),感谢Krahets,K神的一些解析,例如二叉搜索树于双向链表的解析:力扣