深度优先搜索(DFS)
基本概念
深度优先搜索算法(Depth First Search,简称DFS):一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过
或者在搜寻时结点不满足条件
(不满足条件也被称为剪枝),搜索将回溯
到发现节点v的那条边的起始节点。整个进程反复进行
直到所有节点都被访问为止。属于盲目搜索
,最糟糕的情况算法时间复杂度为O(!n)。
算法思想
回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
我这里准备了一张GIF图片,希望能够帮助你理解其中的思想
DFS可以理解为一条路走到底,不撞南墙不回头
撞南墙有两种情况
- 遇到了边界条件(限制条件)
- 遇到了已经走过的路
DFS的另一种结束条件,就是找到了目标出口,也就是找到了题目的答案DFS的本质其实就是枚举
枚举+递归+回溯 = DFS
这位博主写的十分详细,在此引出作为标记
DFS入门级(模板)_ღ江晚吟的博客-优快云博客_dfs入门
1,两数之和
以值为键值,下标为值创建字典
加快速度
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
hashmap={};
for i,num in enumerate(nums):
if hashmap.get(target-num) is not None:
return [hashmap.get(target-num),i]
hashmap[num]=i
17. 电话号码的字母组合 DFS 相同步长的所有路径个数
class Solution(object):
def letterCombinations(self, digits):
"""
:type digits: str
:rtype: List[str]
"""
phone={'2':['a','b','c'],
'3':['d','e','f'],
'4':['g','h','i'],
'5':['j','k','l'],
'6':['m','n','o'],
'7':['p','q','r','s'],
'8':['t','u','v'],
'9':['w','x','y','z']}
res=[]
def dfs(s,index):
if index==len(digits):
res.append(s)
return
for s1 in phone[digits[index]]:
dfs(s+s1,index+1)
if digits:#特殊情况:digits为空时res为[''],而不是[]
dfs('',0)
return res
64. 最小路径和 动态规划 无初始化型
class Solution(object):
def minPathSum(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
n=len(grid)
m=len(grid[0])
dp=[[float('inf')]*m for i in range(2)]
for i in range(n):
for j in range(m):
if i==0 and j==0:
dp[i%2][j]=grid[i][j]
elif i==0:
dp[i%2][j]=dp[i%2][j-1]+grid[i][j]
elif j==0:
dp[i%2][j]=dp[(i-1)%2][j]+grid[i][j]
else:
dp[i%2][j]=min(dp[(i-1)%2][j]+grid[i][j],dp[i%2][j-1]+grid[i][j])
return dp[(n-1)%2][m-1]
69. x 的平方根 二分查找
class Solution(object):
def mySqrt(self, x):
"""
:type x: int
:rtype: int
"""
up=x
down=0
mid=0
if x<=1:
return x
while(up>down):
mid=(up+down)//2
sqrt=mid**2
sqrt1=(mid+1)**2
if sqrt>x:
up=mid
elif sqrt<x:
if sqrt1>x:
break
down=mid
else:
break
return mid
class Solution(object):
def sortColors(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
righ=len(nums)-1
left=0
new=0
while new<righ:
if nums[new]==0:
nums[new],nums[left]=nums[left],nums[new]
left+=1
new+=1
elif nums[new]==1:
new+=1
else:
nums[new],nums[righ]=nums[righ],nums[new]
righ-=1
return nums