八 搜索
1.1 基础
1.1.1 二分
二分查找又称折半查找,它是一种效率较高的查找方法。
二分查找要求
- 目标函数具有单调性(单调递增或者递减)
- 存在上下界(bounded)
- 能够通过索引访问(indexaccessible)
1.1.2 二叉
- 二叉树的遍历方式主要有:先序遍历、中序遍历、后序遍历、层次遍历。
- 先序、中序、后序其实指的是父节点被访问的次序。若在遍历过程中,父节点先于它的子节点被访问,就是先序遍历;父节点被访问的次序位于左右孩子节点之间,就是中序遍历;访问完左右孩子节点之后再访问父节点,就是后序遍历。不论是先序遍历、中序遍历还是后序遍历,左右孩子节点的相对访问次序是不变的,总是先访问左孩子节点,再访问右孩子节点。
- 层次遍历,就是按照从上到下、从左向右的顺序访问二叉树的每个节点。
1.1.3 DFS
- 深度优先遍历
(1 从图中的某个初始点 v 出发,首先访问初始点 v.
(2 选择一个与顶点 v 相邻且没被访问过的顶点 ver ,以 ver 为初始顶点,再从它出发进行深度优先遍历。
(3 当路径上被遍历完,就访问上一个顶点的第 二个相邻顶点。
(4 直到所有与初始顶点 v 联通的顶点都被访问。
1.1.4 BFS
- 广度优先遍历
(1)从图中的某个初始点 v0 出发,首先访问初始点 v0。
(2)接着访问该顶点的所有未访问过的邻接点 v01 v02 v03 ……v0n。
(3)然后再选择 v01 v02 v03 ……v0n,访问它们的未被访问的邻接点,v010 v011 v012……v01n。
(4)直到所有与初始顶点 v 联通的顶点都被访问。
1.2 题目
1.2.1 704. 二分查找
class Solution:
def search(self, nums: List[int], target: int) -> int:
left,right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
elif nums[mid] > target:
right = mid - 1
else:
left = mid + 1
return -1
1.2.2 33 . 搜索旋转排序数组
- 思路: 两段二分 >>> 若
nums[mid]
落第一段区间 >>> 以nums[left]
为基准 >>> 否则以nums[right]
为准
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
elif nums[mid] >= nums[left]:
if nums[left] <= target < nums[mid]:
right = mid - 1
else:
left = mid + 1
else:
if nums[mid] < target <= nums[right]:
left = mid + 1
else:
right = mid - 1
return -1
1.2.3 94 . 二叉树的中序遍历
- 思路: 深度 >>> 递归 >>> 中: 左递归 根加入 右递归
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
ans = []
self.dfs(root, ans)
return ans
def dfs(self, root, ans):
if not root: return
self.dfs(root.left, ans)
ans.append(root.val)
self.dfs(root.right, ans)
1.2.4 101 . 对称二叉树
- 思路: 停止条件 >>> 1. 两边同为空 >>> 2.左右一边为空, 两边不等
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
def dfs(left, right):
if not left and not right:
return True
if not left or not right or left.val != right.val:
return False
return dfs(left.left, right.right) and dfs(left.right, right.left)
return dfs(root.left, root.right)
1.2.5 230 . 二叉搜索树中第K小的元素
- 思路: 利用中序遍历有序即可
class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
stack = []
self.dfs(root, stack)
return stack[k - 1]
def dfs(self, root, stack):
if not root: return
self.dfs(root.left, stack)
stack.append(root.val)
self.dfs(root.right, stack)