码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode-剑指Offer 13机器人运动

时间:2020-07-25 09:22:54      阅读:52      评论:0      收藏:0      [点我收藏+]

标签:oca   运动   nbsp   array   遍历   lse   算法思路   原因   跳过   

这道题我的思路如下:

1)设机器人的下一个位置是(a,b),那么他的上一个位置最多只有4种情况:(a-1,b),(a+1,b),(a,b-1),(a,b+1)

2)判定机器人能否到达位置(a,b),需要判断两个条件,一是他前面4个位置其中之一是否能够到达,二是位置(a,b)的各位数字之和是否大于k,同时满足这两个条件,那么(a,b)才是一个可以到达的位置。

3)位置(0,0)是一定可以到达的,因为这是初始位置

有了上面几个关键点,接下来就是我们的算法思路:

1、方格是m行n列,对应了一个m行n列的数组,用这个数组来保存该位置是否可达,如果位置可达,那么该位置值为1,不可达值为-1,如果还没有判断这个位置,那么这个位置值为0

2、预处理二维数组,根据所在i行j列,用i和j各位数字之和大于k来先给定一些位置不可达的结论,并且将这些位置的值置为-1

3、理论类似于图的广度优先搜索,实现方法类似于二叉树的层序遍历,从位置(0,0)开始,判断他周围的位置是否可达:

  首先将位置(0,0)存入队列

  然后将队首元素出队列,判断他四周的位置是否可达,如果四周的位置的值为1,则跳过不处理这个位置,因为这个位置已经被处理过了,如果这个位置的值为0,说明这个位置是可以到达的,将这个位置的值置为1,并且将这个位置的坐标存入队列,如果这个位置的值为-1,说明这个位置不可以到达,跳过这个位置

  循环上面这个过程,直到队列为空

  此时二维数组中值为1的位置就是可以到达的,值为0的位置就表示虽然该位置坐标各位数之和小于k,但是他周围的位置都不能到达,所以没有路径走到这个位置上,值为-1的位置就是表明不能到达(不能到达的两种原因都可能存在,但是一定有各位数之和大于k这个因素)

所以整个算法的思想就是图的广度优先搜索

代码如下:

 

package main

import "fmt"

func main() {
	fmt.Println(mc(3, 1, 0))
}

// 通过数字之和可以直接判定某些位置不能到达
func reach(x, y, k int) bool {
	tmpArray := []int{x, y}
	sum := 0
	for _, value := range tmpArray {
		for value != 0 {
			sum += (value % 10)
			value /= 10
		}
	}
	if sum <= k {
		return true
	}
	return false
}

func mc(m, n, k int) int {
	res := make([][]int, m)
	for i := 0; i < m; i++ {
		res[i] = make([]int, n)
	}
	res[0][0] = 1
	for i := 0; i < m; i++ {
		for j := 0; j < n; j++ {
			if !reach(i, j, k) {
				res[i][j] = -1
			}
		}
	}
	// queue:=[][]int([0,0],)
	queue := make([][]int, 0)
	queue = append(queue, []int{0, 0})
	// queue[0] = make([]int, 2)
	// queue[0][0] = 0
	// queue[0][1] = 0
	for len(queue) != 0 {
		curValue := queue[0]
		queue = queue[1:]
		if curValue[0]-1 > 0 && res[curValue[0]-1][curValue[1]] == 0 {
			res[curValue[0]-1][curValue[1]] = 1
			var tmpLocation []int
			tmpLocation = append(tmpLocation, curValue[0]-1)
			tmpLocation = append(tmpLocation, curValue[1])
			queue = append(queue, tmpLocation)
		}
		if curValue[0]+1 < m && res[curValue[0]+1][curValue[1]] == 0 {
			res[curValue[0]+1][curValue[1]] = 1
			var tmpLocation []int
			tmpLocation = append(tmpLocation, curValue[0]+1)
			tmpLocation = append(tmpLocation, curValue[1])
			queue = append(queue, tmpLocation)
		}
		if curValue[1]-1 > 0 && res[curValue[0]][curValue[1]-1] == 0 {
			res[curValue[0]][curValue[1]-1] = 1
			var tmpLocation []int
			tmpLocation = append(tmpLocation, curValue[0])
			tmpLocation = append(tmpLocation, curValue[1]-1)
			queue = append(queue, tmpLocation)
		}
		if curValue[1]+1 < n && res[curValue[0]][curValue[1]+1] == 0 {
			res[curValue[0]][curValue[1]+1] = 1
			var tmpLocation []int
			tmpLocation = append(tmpLocation, curValue[0])
			tmpLocation = append(tmpLocation, curValue[1]+1)
			queue = append(queue, tmpLocation)
		}
	}
	num := 0
	for i := 0; i < m; i++ {
		for j := 0; j < n; j++ {
			if res[i][j] == 1 {
				num++
			}
		}
	}
	return num
}

  

leetcode-剑指Offer 13机器人运动

标签:oca   运动   nbsp   array   遍历   lse   算法思路   原因   跳过   

原文地址:https://www.cnblogs.com/gyyyl/p/13375252.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!