> 文档中心 > 《五月集训》(第15天)——深度优先搜索

《五月集训》(第15天)——深度优先搜索


前言:

五月集训,前面为学习内容,想要一起学习的可以看一看,最后的才是五月集训每天的作业

一、知识点

深度优先搜索简单来说就是“装了南墙就回头”,沿着一条路一直走,走不通就回到前一个节点换个方向走。

二、课堂习题

这里的题均出自《算法零基础100讲》
更多知识点等到暑假的集训更新,或者着急的同学可以去看英雄哥的专栏。

三、作业

565. 数组嵌套
401. 二进制手表
1079. 活字印刷
1219. 黄金矿工
解题思路:
1.简单的暴力深搜就能求解,但是会超出时间限制,因此我们需要观察题目的规律对其进行剪枝,我们能直到对于一组走完的数组元素,它会形成一个闭环,其中的任何一个元素作为头部走的都是这个环,因此我们可以对于走过环里的元素进行标注,让其不再作为头部元素进行深搜;
2.深搜枚举,当亮灯数量满足要求时,将之前存起来的时间和小时数,进行判断,符合条件的则存入答案链表中;
3.深搜模板题,简单的hash标注dfs就可以;
4.上下左右走,有满足条件的就继续走,累加价值,当无路可走时,判断这条路累计的价值是否大于答案,然后进行回溯。
代码:

class Solution {    int temp = 0;    public int arrayNesting(int[] nums) { int ans = 0; int[] hash = new int[200010]; for(int i = 0;i < nums.length;i++){     if(hash[i] == -1){  continue;     }     hash[i] = 1;     temp = 1;     dfs(nums,hash,nums[i]);     if(ans < temp){  ans = temp;     } } return ans;    }    public void dfs(int[] nums,int[] hash,int i){ if(hash[i] != 0){     return; } temp++; hash[i] = -1; dfs(nums,hash,nums[i]);    }}
class Solution {    List<String> ans = new ArrayList<>();    int[] times = {8,4,2,1,32,16,8,4,2,1};    public List<String> readBinaryWatch(int turnedOn) { if(turnedOn < 0){     return ans; } dfs(turnedOn,0,0,0); return ans;    }    public void dfs(int num,int start,int h,int min){ if(num == 0){     if(h > 11 || min > 59){  return;     }     StringBuilder temp = new StringBuilder();     temp.append(h);     temp.append(":");     if(min < 10){  temp.append(0);     }     temp.append(min);     ans.add(temp.toString());     return; } for(int i = start;i < 10;i++){     if(i < 4){  h += times[i];     }else{  min += times[i];     }     dfs(num-1,i+1,h,min);     if(i < 4){  h -= times[i];     }else{  min -= times[i];     } }    }}
class Solution {    int[] hash = new int[26];    int ans = 0;    public int numTilePossibilities(String tiles) { for(int i = 0;i < tiles.length();i++){     hash[tiles.charAt(i) - 'A']++; } dfs(hash); return ans;    }    public void dfs(int[] hash){ for(int j = 0;j < 26;j++){     if(hash[j] != 0){  hash[j]--;  ans++;  dfs(hash);  hash[j]++;     } }    }}
class Solution {    int[][] hash;    int ans = 0,temp = 0;    int m,n;    static int[][] move = {{0,1},{1,0},{0,-1},{-1,0}};    public int getMaximumGold(int[][] grid) { m = grid.length; n = grid[0].length; hash = new int[m][n]; for(int i = 0;i < m;i++){     for(int j = 0;j < n;j++){  dfs(grid,i,j);  temp = 0;     } } return ans;    }    public void dfs(int[][] grid,int x,int y){ if(x == -1 || x == m || y == -1 || y == n || grid[x][y] == 0 || hash[x][y] != 0){     if(ans < temp){  ans = temp;     }     return; } hash[x][y] = 1; temp += grid[x][y]; int newx = x,newy = y; for(int i = 0;i < 4;i++){     newx += move[i][0];     newy += move[i][1];     dfs(grid,newx,newy);     newx -= move[i][0];     newy -= move[i][1]; } temp -= grid[x][y]; hash[x][y] = 0;    }}

四、总结

对于算法的掌握还是不够熟练,需要进行反复训练!
另外,剩下的课堂训练题目留到下个月的集训啦(●ˇ∀ˇ●)