22、不同路径III

题目描述:
在二维网格 grid 上,有 4 种类型的方格:

1 表示起始方格。且只有一个起始方格。
2 表示结束方格,且只有一个结束方格。
0 表示我们可以走过的空方格。
-1 表示我们无法跨越的障碍。
返回在四个方向(上、下、左、右)上行走时,从起始方格到结束方格的不同路径的数目,每一个无障碍方格都要通过一次。

示例 1:

输入:[[1,0,0,0],[0,0,0,0],[0,0,2,-1]]
输出:2
解释:我们有以下两条路径:

  1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2)
  2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2)
    示例 2:

输入:[[1,0,0,0],[0,0,0,0],[0,0,0,2]]
输出:4
解释:我们有以下四条路径:

  1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2),(2,3)
  2. (0,0),(0,1),(1,1),(1,0),(2,0),(2,1),(2,2),(1,2),(0,2),(0,3),(1,3),(2,3)
  3. (0,0),(1,0),(2,0),(2,1),(2,2),(1,2),(1,1),(0,1),(0,2),(0,3),(1,3),(2,3)
  4. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2),(2,3)
    示例 3:

输入:[[0,1],[2,0]]
输出:0
解释:
没有一条路能完全穿过每一个空的方格一次。
请注意,起始和结束方格可以位于网格中的任意位置。

提示:

1 <= grid.length * grid[0].length <= 20

比较简单,一个dfs即可。
结尾的end[]数组其实可以省去
代码:

class Solution {
int result = 0;
	public int uniquePathsIII(int[][] grid) {
        int start[] = getstartorend(grid, 1);
        int end[] = getstartorend(grid, 2);
        int num = getzeronum(grid);
        int xstart = start[0];
        int ystart = start[1];
        int xend = end[0];
        int yend = end[1];
       
        boolean visited[][] = new boolean[grid.length][grid[0].length];
   
//        初始化开始为已经访问过
        visited[xstart][ystart] = true;
//        最后一个零表示的是总共有多少个需要访问
//        分别传入的是结束的坐标,当前的x,y坐标,是否访问,已经访问的零的坐标,总共的零的坐标
        dfs(grid, xstart + 1, ystart,  visited, 0,num);
        dfs(grid, xstart - 1, ystart,  visited, 0,num);
        dfs(grid, xstart, ystart + 1,  visited, 0,num);
        dfs(grid, xstart, ystart - 1,  visited, 0,num);
        return result;
    }
	public void dfs(int [][] grid,int x,int y,boolean [][] visited,int num,int total){
		 int []direx = {0,0,-1,1};
		 int []direy = {1,-1,0,0};
    if(!isgetin(grid, x, y,visited)){			
    return ;
		}
		if(grid[x][y] == 2 && num == total){
			result ++;
			return;
		}
//		没有达到指定的数量
		if(grid[x][y] == 2){
			return ;
		}
//		剩下的就是0,可以走的情况
		visited[x][y] = true;
		for (int i = 0; i < 4; i++) {
			int temx = x + direx[i];
			int temy = y + direy[i];
			dfs(grid, temx, temy, visited, num + 1,total);
		}
		visited[x][y] = false;
	}
	
	public boolean isgetin(int [][]grid,int x,int y,boolean [][] visited){
		if(x < 0 || y < 0 || x >= grid.length ||y >= grid[0].length || visited[x][y]
				 || grid[x][y] == -1 ){
			return false;
		}else {
			return true;
		}
	
	}
	
	public int getzeronum (int[][] grid){
		int time = 0;
		for (int[] is : grid) {
			for (int i : is) {
				if(i == 0){
					time ++;
				}
			}
		}
		return time;
	}
	
	public int [] getstartorend(int[][] grid,int num){
		for (int i = 0; i < grid.length; i++) {
			for (int j = 0; j < grid[i].length; j++) {
				if(grid[i][j] == num){
					return new int[]{i,j};
				}
			}
		}
		System.out.println("未找到!!");
		return new int[]{-1,-1};
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值