你要開發一座金礦,地質勘測學家已經探明了這座金礦中的資源分布,並用大小為 m * n 的網格 grid 進行了標註。每個單元格中的整數就表示這一單元格中的**數量;如果該單元格是空的,那麼就是 0。為了判斷收益最大的採礦路線,必須遍歷所有可能的路線,並比較各條路線的收益值.為了使收益最大化,礦工需要按以下規則來開採**:
每當礦工進入乙個單元,就會收集該單元格中的所有**。
礦工每次可以從當前位置向上下左右四個方向走。
每個單元格只能被開採(進入)一次。
不得開採(進入)**數目為 0 的單元格。
礦工可以從網格中 任意乙個 有**的單元格出發或者是停止
====================================
輸入:grid = [[0,6,0],[5,8,7],[0,9,0]]
輸出:24
解釋:[[0,6,0],
[5,8,7],
[0,9,0]]
一種收集最多**的路線是:9 -> 8 -> 7。
====================================
假設我們當前處於位置(i, j),由於需要判斷從當前位置上下左右四個可能方向出發,哪條路徑能夠收集到最多的**量,因此我們需要在上下左右四個可能方向遍歷完成後,向上回溯.當然,回溯本質上就是遞迴方法,但它是一種非尾遞迴的方法.也就是我們需要在子問題遞迴呼叫返回後,才能計算得到當前遞迴呼叫的返回值.因此,回溯可以視作分治演算法,我們將當前問題分解為幾個子問題,計算得到子問題的解後,當前問題的解也就得到了.
假設當前位置為(i, j),如果當前位置為無效位置,則返回0,如果可繼續前進,則分別向上下左右四個可能方向進行遞迴地深度優先搜尋.當上下左右四個可能方向均完成搜尋,判斷哪一條路徑收集**最多.則從當前位置出發所採集到的最多**數量即為當前位置**數量+上下左右四個方向最多收集**量,返回該值.
為了避免對同一單元格的重複搜尋,我們必須紀錄當前前進路徑上經過的所有單元格,在回溯過程中,當進入搜尋時,標記該單元格,當退出搜尋時,取消對該單元格的標記.我們可以使用二維布林陣列進行標記,對於該問題,考慮單元格為0表示無法前進,因此我們可以在進入單元格時將其值修改為0,但退出單元格時,恢復其原始值,同樣可以使用標記的效果.
由於路線可能從所有不為0的單元格開始,所以需要對所有不為0的單元格分別進行以該位置為起點的深度優先搜尋,選擇收集**量最多的線路.
public
class
solution}}
return ans;
}//上下左右四個前進方向
private
static
final
int[
] dirs =,,
,};private
intdfs
(int
grid,
int i,
int j)
grid[i]
[j]= v;
//遞迴退出後,當前位置不在路徑上.
return ret;
}}
Leetcode 1219 黃金礦工
你要開發一座金礦,地質勘測學家已經探明了這座金礦中的資源分布,並用大小為 m n 的網格 grid 進行了標註。每個單元格中的整數就表示這一單元格中的 數量 如果該單元格是空的,那麼就是 0。為了使收益最大化,礦工需要按以下規則來開採 每當礦工進入乙個單元,就會收集該單元格中的所有 礦工每次可以從當...
leetcode 1219 黃金礦工
你要開發一座金礦,地質勘測學家已經探明了這座金礦中的資源分布,並用大小為 m n 的網格 grid 進行了標註。每個單元格中的整數就表示這一單元格中的 數量 如果該單元格是空的,那麼就是 0。為了使收益最大化,礦工需要按以下規則來開採 每當礦工進入乙個單元,就會收集該單元格中的所有 礦工每次可以從當...
LeetCode 1219 黃金礦工
你要開發一座金礦,地質勘測學家已經探明了這座金礦中的資源分布,並用大小為 m n 的網格 grid 進行了標註。每個單元格中的整數就表示這一單元格中的 數量 如果該單元格是空的,那麼就是 0。為了使收益最大化,礦工需要按以下規則來開採 每當礦工進入乙個單元,就會收集該單元格中的所有 礦工每次可以從當...