目录
放牌
员工的重要性
图像渲染
岛屿的周长
被围绕的区域
岛屿的数量
岛屿的最大面积
电话号码的字母组合
二进制手表
组合总和
活字印刷
N皇后
深度优先搜索(Depth First Search)------ 一条道走到黑
假如有编号为1~3的3张扑克牌和编号为1~3的3个盒子,现在需要将3张牌分别放到3个盒子中去,且每个盒子只能放一张牌,一共有多少种不同的放法。
步骤:
1.边界,如果遍历到了最后一个,输出遍历结果
2.遍历每一个牌
1.如果没有使用过,放入牌,盒子标记为1
2.进入下一个遍历
3.回溯,取出最后一个放入的牌
public static void Dfs(int index, int n, int[] boxs, int[] book){
if(index==n+1){//边界:最后一个-->此时牌都放入了,直接输出结果
//输出这一次的遍历结果
for (int i = 1; i <=n ; i++) {
System.out.print(boxs[i]+" ");
}
//一次结果输出后,回车
System.out.println();
return;
}
for(int i=1;i<=n;i++){
//判断当前牌是否用过
if(book[i]==0){
//没有使用过,放入牌,盒子标记为1
boxs[index]=i;
book[i]=1;//i号牌已经使用
//处理下一个盒子
Dfs(index+1,n,boxs,book);
//从下一个盒子回退到当前盒子,取出当前盒子的牌
book[i]=0;
}
}
}
public static void main(String[] args) {
int n;
Scanner sc = new Scanner(System.in);
n = sc.nextInt();//盒子和牌个数
int[] boxs = new int[n + 1];//盒子
int[] books = new int[n + 1];//牌
Dfs(1, n, boxs, books);
}
class Solution {
public int DFS(Map info, int id){
//当前员工的import和他所有下属的import
Employee curE=info.get(id);//得到id
int sum=curE.importance;//通过id,得到import和
for (int subId: curE.subordinates) {//遍历下属,得到总和
sum+=DFS(info,subId);
}
return sum;
}
public int getImportance(List employees, int id) {
if(employees.isEmpty()){
return 0;
}
Map info=new HashMap<>();
//信息放入info中
for(Employee e:employees){
info.put(e.id,e);//从list中取出list中的元素,放入info中
}
//遍历总和
return DFS(info,id);
}
}
步骤:
floodFill
1.得到矩阵的长宽,指定位置原本的颜色
2.创建数组book,判断该位置是否遍历过
3.进入dfs
4.输出结果image
dfs
1.把当前位置颜色改变,标记为遍历过
2.遍历四个方向
3.得到新的位置
4.判断位置是否合法
5.判断是否和原颜色相同,是否标记过
5.满足要求,进行递归
class Solution {
public int[][] floodFill(int[][] image, int sr, int sc, int color) {
int oldcolor=image[sr][sc];
int row=image.length;
int col=image[0].length;
int[][] book=new int[row][col];
dfs(image,sr,sc,book,row,col,oldcolor,color);
return image;
}
int[][] next={{1,0},{-1,0},{0,1},{0,-1}};
public void dfs(int[][] image,int curx,int cury,int[][] book,int row,int col,int oldcolor,int color){
image[curx][cury]=color;
book[curx][cury]=1;
for(int i=0;i<4;i++){
int newx=curx+next[i][0];
int newy=cury+next[i][1];
if(newx>=row || newx<0 || newy>=col || newy<0){
continue;
}
if(image[newx][newy]==oldcolor && book[newx][newy]==0){
dfs(image,newx,newy,book,row,col,oldcolor,color);
}
}
}
}
遍历,判断是不是陆地,如果是进入dfs
class Solution {
public int islandPerimeter(int[][] grid) {
for(int i=0;i=grid.length || j<0 || j>=grid[0].length){
return 1;
}
//水域+1
if(grid[i][j]==0){
return 1;
}
//遍历过 在内部,周长不增加
if(grid[i][j]!=1){
return 0;
}
//遍历过,防止再次遍历
grid[i][j]=2;
return dfs(grid,i-1,j)+dfs(grid,i+1,j)+dfs(grid,i,j+1)+dfs(grid,i,j-1);
}
}
从四个边遍历,把边上的O变为A,把剩下的O(此时的O都是被包围的)变为X,把A变为O
步骤:
class Solution {
public void solve(char[][] board) {
if(board==null){
return ;
}
int row=board.length;
int col=board[0].length;
int[][] book=new int[row][col];
for(int i=0;i=row || ny<0 || ny>=col){
continue;
}
if(board[nx][ny]=='O'){
dfs(board,nx,ny,row,col,book);
}
}
}
}
步骤
class Solution {
public int numIslands(char[][] grid) {
int ret=0;
int row=grid.length;
int col=grid[0].length;
int[][] book=new int[row][col];
for(int i=0;i=row || nx<0 || ny>=col || ny<0){
continue;
}
if(grid[nx][ny]=='1' && book[nx][ny]==0){
dfs(grid,book,row,col,nx,ny);
}
}
}
}
步骤
class Solution {
public int maxAreaOfIsland(int[][] grid) {
if(grid.length==0){
return 0;
}
int row=grid.length;
int col=grid[0].length;
int[][] book=new int[row][col];
int max=0;
int ret=0;
for(int i=0;i=row || nx<0 || ny>=col || ny<0){
continue;
}
if(grid[nx][ny]==1 && book[nx][ny]==0){
r+=dfs(grid,book,row,col,nx,ny);
}
}
return r;
}
}
步骤
public List letterCombinations(String digits) {
List ret=new ArrayList<>();
StringBuilder curStr=new StringBuilder("");
dfs(digits,ret,curStr,0);
// 数组 结果存放 当前字符串 遍历的长度
return ret;
}
String[] mapString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
private void dfs(String digits, List ret, StringBuilder curStr, int curDepth) {
//边界
if(curDepth==digits.length()){
if(curStr.length()!=0){
ret.add(curStr.toString());
}
return;
}
//找到对应位置
int curMapIndex=digits.charAt(curDepth)-'0';//得到当前的数字
String curMap=mapString[curMapIndex];//通过数字找到该下标的所有字母
for (int i = 0; i < curMap.length(); i++) {
//当前字符串加入新的字母(得到的字符串的每个元素依次遍历)
dfs(digits, ret, curStr.append(curMap.charAt(i)), curDepth+1);
//结束后,去掉新加的字母,为下一个字母的加入做准备
curStr.deleteCharAt(curStr.length()-1);
}
}
步骤:
1. 判断边界 h>11 m>59 不满足
2.如果在边界上,还需要的灯的个数为0 时间放入list中
3.把十个灯遍历,得到对应的时间
class Solution {
int[] hs={1,2,4,8,0,0,0,0,0,0};
int[] ms={0,0,0,0,1,2,4,8,16,32};
List list=new ArrayList<>();
public List readBinaryWatch(int turnedOn) {
dfs(turnedOn,0,0,0);
return list;
}
public void dfs(int turnedOn,int index,int h,int m){
if(h>11 || m>59){
return ;
}
if(turnedOn==0){
list.add(h+":"+(m<10?"0":"")+m);
}
for(int i=index;i<10;i++){
dfs(turnedOn-1,i+1,h+hs[i],m+ms[i]);
}
}
}
dfs:
等于目标返回
从当前位置到最后一个位置,遍历
如果当前位置的值大于目标值,continue
深度搜索
去掉最后一个元素
class Solution {
public List> combinationSum(int[] candidates, int target) {
List> solutions=new ArrayList<>();
List solution=new ArrayList<>();
if(candidates.length==0){
return solutions;
}
int curSum=0;
dfs(solutions,solution,candidates,target,curSum,0);
return solutions;
}
public static void dfs(List> solutions,List solution,int[] candidates,int target,int curSum,int index){
if(curSum>=target){
if(curSum==target){
List newS=new ArrayList<>();
for(int e:solution){
newS.add(e);
}
solutions.add(newS);
}
return;
}
for(int i=index;itarget){
continue;
}
solution.add(candidates[i]);
dfs(solutions,solution,candidates,target,curSum+candidates[i],i);
solution.remove(solution.size()-1);
}
}
}
因为每个只能使用一次,所有要标记是否使用过,如果没有使用过标记为0,进入遍历
dfs:
如果curStr长度不为0,放入set中
从0开始遍历titles
如果没有遍历过,标记为遍历,进入dfs,去到新加的,标记为没有遍历过
class Solution {
public int numTilePossibilities(String tiles) {
if(tiles.length()==0){
return 0;
}
int[] book=new int[tiles.length()];
Set total=new HashSet<>();
StringBuilder curStr=new StringBuilder();
dfs(tiles,curStr,book,total);
return total.size();
}
private void dfs(String tiles, StringBuilder curStr, int[] book, Set total) {
if(curStr.length()!=0){
total.add(curStr.toString());
}
for(int i=0;i
dfs:
isVaild:判断列,行列和,行列差知否冲突,
transResult:
class pair{
int x;
int y;
public pair(int x,int y){
this.x=x;
this.y=y;
}
}
public class Solution {
public List> solveNQueens(int n) {
List> solutions=new ArrayList<>();
List solution=new ArrayList();
dfs(solutions,solution,0,n);
return transResult(solutions,n);
}
private List> transResult(List> solutions, int n) {
//遍历每一个方案
List tmp=new ArrayList<>();
//把每一种方案转换成string形式
List> ret=new ArrayList<>();
for(List solution:solutions){
List solutionString=new ArrayList<>();
for(int i=0;i curRet=new ArrayList<>();
for(StringBuilder s:solutionString){
curRet.add(s.toString());
}
ret.add(curRet);
}
return ret;
}
public void dfs(List> solutions,
List solution, int curRow, int n){
if(curRow==n){
List newS=new ArrayList<>();
for(pair p:solution){
newS.add(p);
}
solutions.add(newS);
}
for(int i=0;i solution, int row, int col) {
for(pair i:solution){
if(i.y==col || i.x+i.y==row+col || i.x-i.y==row-col){
return false;
}
}
return true;
}
}