2020年9~10月
94.二叉树的中序遍历
给定一个二叉树,返回它的中序遍历。
实例:
输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2]
递归版:
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, val=0, left=None, right=None): 4 # self.val = val 5 # self.left = left 6 # self.right = right 7 8 class Solution: 9 def inorderTraversal(self, root: TreeNode) -> List[int]: 10 def dfs(cur): 11 if not cur: 12 return 13 dfs(cur.left) 14 res.append(cur.val) 15 dfs(cur.right) 16 17 res = [] 18 dfs(root) 19 return res
迭代版:
1 class Solution: 2 def inorderTraversal(self, root: TreeNode) -> List[int]: 3 4 stack, output = [], [] 5 node = root 6 7 if root == None: 8 return output 9 10 while node or stack: #node和stack都为空,即查完 11 while node: #node为空,左边没有节点了 12 stack.append(node) 13 node = node.left 14 node = stack.pop() #左边没有节点了,就输出栈顶节点值 15 16 output.append(node.val) 17 node = node.right 18 return output
226.翻转二叉树
示例:
输入:
4 / \ 2 7 / \ / \ 1 3 6 9
输出:
4 / \ 7 2 / \ / \ 9 6 3 1
递归版:
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 8 class Solution: 9 def invertTree(self, root: TreeNode) -> TreeNode: 10 11 if root == None: 12 return root 13 14 self.invertTree(root.left) 15 self.invertTree(root.right) 16 17 if root: 18 root.left, root.right = root.right, root.left 19 20 return root
142.环形链表II
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。
示例:
1 输入:head = [3,2,0,-4], pos = 1 2 输出:tail connects to node index 1 3 解释:链表中有一个环,其尾部连接到第二个节点。
1 # Definition for singly-linked list. 2 # class ListNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.next = None 6 7 class Solution: 8 def detectCycle(self, head: ListNode) -> ListNode: 9 10 slow, fast = head, head 11 while fast and fast.next: #因为慢指针总会进环的,如果有环的话,快慢指针终会相遇 12 slow, fast = slow.next, fast.next.next 13 if fast == slow: 14 break 15 #无环(不满足while循环条件才退出) 16 if fast == None or fast.next == None: 17 return None 18 19 #计算环的起点(break退出) 20 pos = head 21 while pos != slow: 22 pos, slow = pos.next, slow.next 23 return pos
理解一下环的起点计算方法:https://blog.csdn.net/weixin_40673608/article/details/86762231
209.长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3]
是该条件下的长度最小的子数组。
方法一:复杂度O(n^2)
1 class Solution: 2 def minSubArrayLen(self, s, nums): 3 minLen = len(nums)+1 4 for i, _ in enumerate(nums): 5 sum_all = 0 6 for j, tmp in enumerate(nums[i:]): 7 sum_all += tmp 8 if sum_all >= s: 9 minLen = min(minLen, j+1) 10 if minLen == len(nums) + 1: 11 return 0 12 return minLen
方法二:双指针
1 class Solution: 2 def minSubArrayLen(self, s, nums): 3 if not nums: 4 return 0 5 6 i, j, total = 0, 0, 0 # i,j表示前后指针 7 n = len(nums) 8 minL = n + 1 9 while i < n: 10 if j < n and total < s: # j还没到末尾且数组和小于s 11 total += nums[j] 12 j += 1 13 else: 14 total -= nums[i] 15 i += 1 16 if total >= s: 17 minL = min(minL, j - i) 18 19 if minL == n + 1: 20 return 0 21 return minL
剑指Offer42
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
要求时间复杂度为O(n)。
输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6
1 class Solution: 2 def maxSubArray(self, nums: List[int]) -> int: 3 max_num = nums[0] 4 for i in range(1, len(nums)): 5 nums[i] = max(nums[i-1] + nums[i], nums[i]) #以num[i]为末尾元素的子元素数组的和的最大值 6 max_num = max(max_num, nums[i]) #所有子数组和的最大值 7 return max_num