1. 程式人生 > 其它 >劍指 Offer 13. 機器人的運動範圍(中等)

劍指 Offer 13. 機器人的運動範圍(中等)

通過率52.5%

題目連結

題目描述:

地上有一個m行n列的方格,從座標 [0,0] 到座標 [m-1,n-1] 。一個機器人從座標 [0, 0] 的格子開始移動,它每次可以向左、右、上、下移動一格(不能移動到方格外),也不能進入行座標和列座標的數位之和大於k的格子。例如,當k為18時,機器人能夠進入方格 [35, 37] ,因為3+5+3+7=18。但它不能進入方格 [35, 38],因為3+5+3+8=19。請問該機器人能夠到達多少個格子?

示例 1:

輸入:m = 2, n = 3, k = 1
輸出:3

示例 2:

輸入:m = 3, n = 1, k = 0
輸出:1

提示:

1 <= n,m <= 100
0 <= k<= 20

思路:

1. 深搜,有三個注意點:

  • 機器人的前進方向:雖然題中說機器人東南西北四個方向都能走,不過就得出答案而言,考慮東和南兩個方向就行了
  • 標記走過的格子:用set記錄走過的格子,這裡一開始我將座標以[i, j]陣列形式存進set了,但是這樣set記錄的就是陣列物件在記憶體中的地址,是無法正確記錄走過的格子的,還是看了官網中Gatsby的題解之後才想到可以將座標以字串的形式儲存set.add(`${i}, ${j}`)
  • 求座標數位和:抽成一個函式,隨時呼叫,我一直是用常規法迴圈求餘,題解中用庫函式求數位和的想法我之前也是沒有想到的,不是捧高踩低,權當多瞭解一些解法

2. 廣搜

我一般能用深搜的就不用廣搜,兩者原理都差不多,不過廣搜要用到佇列,這裡也寫寫鞏固一下

程式碼:

1. 深搜

 1 /*JavaScript*/
 2 /**
 3  * @param {number} m
 4  * @param {number} n
 5  * @param {number} k
 6  * @return {number}
 7  */
 8 // 求數位和
 9 var getBitSum = function(x) {
10     let sum = 0
11     while(x) {
12         sum += x % 10
13         x = Math.floor(x / 10)
14     }
15     return sum
16     //
利用庫函式 17 // return x.toString().split('').reduce((ans, cur) => Number(ans) + Number(cur), 0) 18 } 19 // 深搜 20 var dfs = function(m, n, i, j, k, set) { 21 if(i < 0 || j < 0 || i >= m || j >= n || set.has(`${i}, ${j}`)) return 0 22 set.add(`${i}, ${j}`) 23 let ans = getBitSum(i) + getBitSum(j) 24 if(ans > k) return 0 25 return 1 + dfs(m, n, i, j+1, k, set) + dfs(m, n, i+1, j, k, set) 26 } 27 28 var movingCount = function(m, n, k) { 29 const set = new Set() 30 return dfs(m, n, 0, 0, k, set) 31 };

2. 廣搜

 1 /*JavaScript*/
 2 /**
 3  * @param {number} m
 4  * @param {number} n
 5  * @param {number} k
 6  * @return {number}
 7  */
 8 // 求數位和
 9 var getBitSum = function(x) {
10     let sum = 0
11     while(x) {
12         sum += x % 10
13         x = Math.floor(x / 10)
14     }
15     return sum
16     // 利用庫函式
17     // return x.toString().split('').reduce((ans, cur) => Number(ans) + Number(cur), 0)
18 }
19 // 廣搜
20 var movingCount = function(m, n, k) {
21     const set = new Set()
22     const que = new Array()
23     que.push([0, 0])
24     while(que.length) {
25         let [i, j] = que.shift() //陣列的解構賦值
26         if(i < 0 || j < 0 || i >= m || j >= n || set.has(`${i}, ${j}`) || getBitSum(i) + getBitSum(j) > k) continue
27         set.add(`${i}, ${j}`)
28         que.push([i, j+1], [i+1, j])
29     }
30     return set.size
31 };