classSolution(object): defdetectCycle(self, head): """ :type head: ListNode :rtype: ListNode """ defsecond_cycle(slow, fast, head): # 双指针找寻入口节点 fast = head # 双指针相遇处为入口节点,包含a=0的情况 while fast != slow: slow = slow.next fast = fast.next return slow
slow = head fast = head # 外部循环终止条件: 快指针到达链表末端 while fast and fast.next: slow = slow.next fast = fast.next.next # 内部循环终止条件: 快慢指针相遇 if slow == fast: return second_cycle(slow, fast, head) returnNone
# 别人的代码 classSolution: defmaxArea(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
## 涉及到结果取最值用min/max
# 我的代码 classSolution(object): defmaxArea(self, height): """ :type height: List[int] :rtype: int """ right = len(height) - 1 left = 0 area = 0 while left != right: new_area = (right - left) * min(height[left], height[right]) if new_area > area: area = new_area if height[left] < height[right]: left += 1 continue if height[left] >= height[right]: right -= 1 continue return area
classSolution(object): deftwoSum(self, numbers, target): """ :type numbers: List[int] :type target: int :rtype: List[int] """ left = 0 right = len(numbers) - 1 while left < right: s = numbers[left] + numbers[right] if s == target: return [left+1,right+1] if s > target: right -= 1 if s < target: left += 1 return []
classSolution(object): deflengthOfLongestSubstring(self, s): """ :type s: str :rtype: int """ # 1. 定义需要维护的变量 suma, max_avg = 0, -float('inf') # 2. 定义滑动窗口的双指针 left = 0 for right inrange(len(nums)): # 3. 更新滑动窗口 suma += nums[right] if right - left + 1 > k: suma -= nums[left] left += 1 # 4. 更新需要维护的变量 if right - left + 1 == k: max_avg = max(max_avg, suma / float(k)) return max_avg
## python正无穷float('inf')/负无穷-float('inf')
长度为定值时也可以指维护单指针,另一指针由单指针和定长k计算得到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
classSolution(object): deffindMaxAverage(self, nums, k): """ :type nums: List[int] :type k: int :rtype: float """ sums = 0 largest = float('-inf') for i, num inenumerate(nums): sums += num if i >= k: sums -= nums[i - k] if i >= k - 1: largest = max(sums, largest) return largest / float(k)
classSolution: deftwoSum(self, nums: List[int], target: int) -> List[int]: hashtable = dict() for i, num inenumerate(nums): if target - num in hashtable: return [hashtable[target - num], i] hashtable[nums[i]] = i return []
deflower_bound1(nums, target): # 闭区间 [left, right] l = 0 r = len(nums) - 1 while l <= r: # l=r时为单元素区间nums[l](nums[r]) m = (l + r) // 2 if nums[m] < target: l = m + 1# 新区间 [mid+1, right] else: r = m - 1# 新区间 [left, mid-1] return l
deflower_bound2(nums, target): # 左闭右开区间 [left, right) l = 0 r = len(nums) while l < r: # l<r时为单元素区间nums[l] m = (l + r) // 2 if nums[m] < target: l = m + 1# 新区间 [mid+1, right) else: r = m # 新区间 [left, mid) return l # left/right
deflower_bound3(nums, target): # 开区间 (left, right) l = -1 r = len(nums) while l+1 < r: # # l+1<r时为单元素区间nums[l+1] m = (l + r) // 2 if nums[m] < target: l = m # 新区间 (mid, right) else: r = m # 新区间 (left, mid) return r
classSolution(object): defsearchInsert(self, nums, target): """ :type nums: List[int] :type target: int :rtype: int """ # 闭区间 [left, right] l = 0 r = len(nums) - 1 while l <= r: # l=r时为单元素区间nums[l](nums[r]) m = (l + r) // 2 if nums[m] < target: l = m + 1# 新区间 [mid+1, right] else: r = m - 1# 新区间 [left, mid-1] return l
classSolution(object): defmySqrt(self, x): """ :type x: int :rtype: int """ l = 1 r = x while l <= r: m = (l + r) // 2 if m*m <= x: l = m + 1 else: r = m - 1 return r # l-1
classSolution(object): deffindPeakElement(self, nums): """ :type nums: List[int] :rtype: int """ l = 0 r = len(nums) - 2 while l <= r: m = (l + r) // 2 if nums[m] < nums[m+1]: l = m + 1 else: r = m - 1 return l # r+1
# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right classSolution(object): defisSameTree(self, p, q): """ :type p: TreeNode :type q: TreeNode :rtype: bool """ # 归的边界条件 if p isNoneor q isNone: return p is q # 递的主体和判断 return p.val == q.val and self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right # 哦莫!第一次自己写出来还一次过的! classSolution(object): defisSymmetric(self, root): """ :type root: TreeNode :rtype: bool """ p = root.left q = root.right defisSy(p,q): if p isNoneor q isNone: return p is q return p.val == q.val and isSy(p.left, q.right) and isSy(p.right, q.left) return isSy(p,q)
# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right classSolution(object): deflevelOrder(self, root): """ :type root: TreeNode :rtype: List[List[int]] """ if root isNone: return [] res = [] que = [root] while que: res.append([node.val for node in que]) # 维护队列实现BFS new_que = [] for node in que: if node.left: new_que.append(node.left) if node.right: new_que.append(node.right) que = new_que return res
# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right classSolution(object): defrightSideView(self, root): """ :type root: TreeNode :rtype: List[int] """ if root isNone: return [] res = [] que = [root] while que: res.append(que[-1].val) new_que = [] for node in que: if node.left: new_que.append(node.left) if node.right: new_que.append(node.right) que = new_que return res
# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right classSolution(object): defzigzagLevelOrder(self, root): """ :type root: TreeNode :rtype: List[List[int]] """ if root isNone: return [] res = [] que = [root] cnt = 0 while que: cur_res = [node.val for node in que] if cnt % 2 == 1: res.append(cur_res[::-1]) else: res.append(cur_res) new_que = [] for node in que: if node.left: new_que.append(node.left) if node.right: new_que.append(node.right) que = new_que cnt += 1 return res
二叉搜索树
二叉搜素树的特点:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
二分搜索树遍历分为两大类,深度优先遍历和层序遍历。
深度优先遍历分为三种:先序遍历(preorder tree walk)、中序遍历(inorder tree walk)、后序遍历(postorder tree walk),分别为:
# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right classSolution(object): defisValidBST(self, root, left=-float("inf"), right=float("inf")): """ :type root: TreeNode :rtype: bool """ if root isNone: returnTrue value = root.val return left < value < right and self.isValidBST(root.left,left,value) and self.isValidBST(root.right,value,right)
classSolution(object): defrecoverTree(self, root): """ :type root: TreeNode :rtype: None Do not return anything, modify root in-place instead. """ # 中序遍历得到数组 nodes = [] definorder(root, nodes): ifnot root: return inorder(root.left, nodes) nodes.append(root) inorder(root.right, nodes) inorder(root, nodes) # 找出并交换违背有序的节点 big, small = None, None pre = nodes[0] for i inrange(1,len(nodes)): if pre.val>nodes[i].val: small = nodes[i] ifnot big: big = pre pre = nodes[i] if big and small: big.val,small.val = small.val,big.val