go语言刷题:1091. 计算在网格中从原点到特定点的最短路径长度

题目

给你一个 n x n 的二进制矩阵 grid 中,返回矩阵中最短 畅通路径 的长度。如果不存在这样的路径,返回 -1 。

二进制矩阵中的 畅通路径 是一条从 左上角 单元格(即,(0, 0))到 右下角 单元格(即,(n - 1, n - 1))的路径,该路径同时满足下述要求:

路径途经的所有单元格都的值都是 0 。
路径中所有相邻的单元格应当在 8 个方向之一 上连通(即,相邻两单元之间彼此不同且共享一条边或者一个角)。
畅通路径的长度 是该路径途经的单元格总数。

示例 1:

输入:grid = [[0,1],[1,0]] 输出:2

思路:

  1. 从 {0,0}出发【加入队列】,经过八个方向
  2. 每次到达一个点,只要满足条件,就加入队列,加入队列意味着下一轮会从该节点出发[也就是 A点出发到达B点,下次以B点为起点出发到达C点,每次到达一个点后,就以到达的点为起点]
  3. 已经被走过的点就不用再走了,应为那个点说明有人提前到过了
  4. 只有当前到达的点 是 右下角的点 就可以直接返回,不需要遍历剩余的
    注: 因为是最短路径,需要明确并认同,最先到达右下角的一次走法,最短路径可以理解为,多个人A从点出发去B点,每个人的速度相同,那么最先到达B点肯定是找到最短路径的那个人边界。
  5. 如果只有一个点,并且为0 ,那么直接返回 1 [也可以不提前判断,放到最后直接返回左下角点的值即可]
  6. 如果左上角或者右下角的点 是 1 那么说明没有路径直接返回 -1
  7. 由于需要的是 路径经过的格子数,因此只需要对 grid[0][0]提前赋值为 1,赋值为1能同时保证下一轮不会再回到起点

解决方法

func shortestPathBinaryMatrix(grid [][]int) int {

	// 边界条件1 如果左上角第一个数为0,则没有解
	if grid[0][0] == 1 {
		return -1
	}
	// 边界条件2 如果矩阵长度是1且第一个数是1,则也没有解
	if len(grid) == 1 && len(grid[0]) == 1 {
		return 1
	}

	// 创建搜索方向
	var direction = [][]int{
		{-1, -1},
		{-1, 0},
		{-1, 1},
		{0, 1},
		{0, -1},
		{1, -1},
		{1, 0},
		{1, 1},
	}

	// 创建访问列表,布尔矩阵
	visited := make([][]bool, 0)
	// 创建路径矩阵,整型矩阵
	distance := make([][]int, 0)
	// 创建矩阵
	for i := 0; i < len(grid); i++ {
		visited = append(visited, make([]bool, len(grid[0])))
		distance = append(distance, make([]int, len(grid[0])))
	}

	// 初始化矩阵
	visited[0][0], distance[0][0] = true, 1

	// 创建列表,用于记录坐标值:(x)行的索引值*行数 + (y)列数
	queue := []int{0}

	// 当坐标数大于0时
	for len(queue) > 0 {
		// 更新列表
		cur := queue[0]
		queue = queue[1:]
		// 解析切片中的横纵坐标
		curx, cury := cur/len(grid[0]), cur%len(grid[0])
		// 遍历8联通域每个方向上的值
		for d := 0; d < 8; d++ {
			nextx := curx + direction[d][0]
			nexty := cury + direction[d][1]
			// 坐标在表格内 && 该位置没有走过 && 该位置的值=0
			if isInBoard(grid, nextx, nexty) && !visited[nextx][nexty] && grid[nextx][nexty] == 0 {
				// 向切片中存入坐标值
				queue = append(queue, nextx*len(grid[0])+nexty)
				// 设置访问矩阵对应的坐标为true
				visited[nextx][nexty] = true
				// 更新距离矩阵中对应的值
				distance[nextx][nexty] = distance[curx][cury] + 1
				if nextx == len(grid)-1 && nexty == len(grid[0])-1 {
					return distance[nextx][nexty]
				}
			}
		}
	}
	// 坐标数等于0,说明没有,则返回-1
	return -1
}

func isInBoard(board [][]int, x, y int) bool {
	return x >= 0 && x < len(board) && y >= 0 && y < len(board[0])
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值