广度优先搜索一层一层地进行遍历,每层遍历都是以上一层遍历的结果作为起点,遍历一个距离能访问到的所有结点。遍历过的结点不能再次被遍历。
设 di 表示第 i 个节点与根节点的距离,推导出一个结论:对于先遍历的节点 i 与后遍历的节点 j,有 di <= dj。
应用场景:无权图的最短路径。
程序实现:1、队列,用来存储每一轮遍历得到的节点;2、标记,对于遍历过的节点,应该将它标记,防止重复遍历。
leetcode例题:
class Solution {
public int shortestPathBinaryMatrix(int[][] grid) {
if(grid==null||grid.length==0||grid[0].length==0) return -1;
int m=grid.length,n=grid[0].length;
//搜索时用来更新下一个点坐标
int[][] dir={{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1}};
//存储每一轮遍历到的节点坐标
Queue>queue=new LinkedList<>();
//根节点入队
queue.add(new Pair<>(0,0));
//记录路径长度
int pathLength=0;
while(!queue.isEmpty()){
//记录当前队列中的所有结点
int size=queue.size();
//经过一轮遍历,更新路径长度
pathLength++;
while(size-->0){
//节点出队
Paircur=queue.poll();
int x=cur.getKey(),y=cur.getValue();
//剪枝
if(grid[x][y]==1){
continue;
}
//遍历到目标节点,返回
if(x==m-1&&y==n-1){
return pathLength;
}
//标记该节点已被遍历
grid[x][y]=1;
for(int[] d:dir){
//更新当前节点的下一个可选节点
int new_x=x+d[0],new_y=y+d[1];
if(new_x<0||new_x>=m||new_y<0||new_y>=n){
continue;
}
//满足条件的下一轮节点入队
queue.add(new Pair<>(new_x,new_y));
}
}
}
return -1;
}
}
广度优先搜索一层一层遍历,每一层得到的所有新节点,要用队列存储起来以备下一层遍历的时候再遍历。而深度优先搜索在得到一个新节点时立即对新节点进行遍历,直到没有新节点了,此时返回。
解决问题:从一个节点出发,使用DFS对一个图进行遍历时,能够遍历到的节点都是从初始节点可达的,可用来求解这种可达性问题。
程序实现:1、栈,用栈来保存当前节点信息,当遍历新节点返回时能够继续遍历当前节点。可以使用递归栈。2、标记,和BFS一样同样需要对已经遍历过的节点进行标记。
leetcode例题:
class Solution {
private int m,n;
private int[][] dir={{0,-1},{-1,0},{0,1},{1,0}};
public int maxAreaOfIsland(int[][] grid) {
if(grid==null||grid.length==0||grid[0].length==0){
return 0;
}
m=grid.length;
n=grid[0].length;
int maxArea=0;
for(int i=0;i=m||y<0||y>=n||grid[x][y]==0){
return 0;
}
//标记已经遍历过
grid[x][y]=0;
int area=1;
for(int[] d:dir){
area+=dfs(grid,x+d[0],y+d[1]);
}
return area;
}
}
Backtracking(回溯)属于DFS。普通DFS主要用在可达性问题,这种问题只要执行到特定的位置然后返回即可。而Backtracking主要用于求解排列组合问题,这种问题在执行到特定的位置返回之后还会继续执行求解过程。
程序实现注意问题:在访问一个元素进入新的递归调用时,需要将新元素标记为已经访问,这样才能在继续递归调用时不用重复访问该元素;但是在递归返回时,需要将元素标记为未访问,因为只需要保证在一个递归链中不同时访问一个元素,可以访问已经访问过但是不在当前递归链中的元素。
leetcode例题:
class Solution {
public List restoreIpAddresses(String s) {
Listres=new ArrayList<>();
StringBuilder sb=new StringBuilder();
backtracking(0,sb,res,s);
return res;
}
private void backtracking(int k,StringBuilder sb,Listres,String s){
//递归结束条件
if(k==4||s.length()==0){
if(k==4&&s.length()==0){
res.add(sb.toString());
}
return;
}
//对于255来说,依次截取2、25、255
for(int i=0;i
参考链接:https://github.com/CyC2018/CS-Notes/blob/master/notes/Leetcode%20%E9%A2%98%E8%A7%A3%20-%20%E6%90%9C%E7%B4%A2.md