LeetCode 329. Longest Increasing Path in a Matrix

這次我們的主題是深度優先搜索,在LeetCode上按照慣例找了一道難度爲hard但通過率最高的題,但是我發現最高的那道題情況有點複雜,所以我覺得選擇了這一道通過率次高的 Longest Increasing Path in a Matrix 先上題目吧

--------------------------------這是題目-----------------------------

Given an integer matrix, find the length of the longest increasing path.

From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed).

Example 1:

nums = [
  [9,9,4],
  [6,6,8],
  [2,1,1]
]

Return 4
The longest increasing path is [1, 2, 6, 9].

Example 2:

nums = [
  [3,4,5],
  [3,2,6],
  [2,2,1]
]
Return 4
The longest increasing path is [3, 4, 5, 6]. Moving diagonally is not allowed.

--------------------------------這是題解-----------------------------------

題目已經很淺顯易懂了,就是從一個矩陣中找到一條最長的遞增序列,得到這個序列的長度即爲答案,可以上下左右找,不能找對角線。有沒有和迷宮很像呢?的確是很像,或者說代碼都很相似,改了一下判斷條件而已。

大概思路就是從一個點開始,檢索上下左右各個方向,如果找到有比這個數小的,那麼就以這個小的數爲起點,繼續用相同的方法檢索,直到這個數的周圍沒有比它更小的數了,那麼從這個局部最小數開始到我們最開始的起點就構成了一個遞增序列,使用完深度優先搜索我們就可以得到從這個點開始的最長序列長度。使用記憶化搜索可以節省一定的時間開銷。那麼我們只要再遍歷一遍整個矩陣,對每個點使用一次DFS我們就能得到一條全局最長遞增序列。

思路很簡單,代碼實現起來也不困難,我使用了一種寫起來最好想的一種方法,你問我爲什麼,因爲我懶啊~

class Solution {
public:
	int dfs(vector<vector<int> >&m,vector<vector<int> >&dp,int i,int j,int row,int col)
	{
		if(dp[i][j]>0)
		return dp[i][j];
		int left=1,right=1,up=1,down=1;
		if(i>0&&m[i-1][j]<m[i][j])//向上搜索,下面同理 
		up=1+dfs(m,dp,i-1,j,row,col);
		if(i<row-1&&m[i+1][j]<m[i][j])
		down=1+dfs(m,dp,i+1,j,row,col);
		if(j>0&&m[i][j-1]<m[i][j])
		left=1+dfs(m,dp,i,j-1,row,col);
		if(j<col-1&&m[i][j+1]<m[i][j])
		right=1+dfs(m,dp,i,j+1,row,col);
		dp[i][j]=max(max(up,down),max(left,right));//記憶化搜索 
		return dp[i][j];
	}
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        int row=matrix.size();
        if(row==0)//這是一個坑,測試點給了一個爲空的矩陣,如果不判斷是會產生空指針引用的錯誤 
        return 0;
        int col=matrix[0].size();
        vector<vector<int> >dp(row,vector<int>(col,0));//聲明一個row*col的全0矩陣,用於記錄從(i,j)開始的最長遞增序列的長度 
        int ans=0;
        for(int i=0;i<row;i++)//遍歷矩陣,得到全局最優解 
        for(int j=0;j<col;j++)
        {
        	ans=max(ans,dfs(matrix,dp,i,j,row,col));
		}
		return ans;
    }
};

’對於dfs函數中的向四周搜索的方法有一種巧妙的寫法,是我在算法書上看到過的,大概就是用一個二維數組來設定上下左右的變化量比如(1,0),(-1,0),(0,1),(0,-1)分別就表示向下,上,右,左,這樣的話用一個循環就可以寫完上面那寫了四種情況的八行語句,什麼?你問我爲什麼不用,都說了因爲我懶啊,說起來容易,到時調起bug來就呵呵了,所以何必不用一種簡單直接的寫法來寫呢,還不容易出錯,時間複雜度還都是一樣的,套用我們老師的一句話送給大家:不要刻意追求技巧。簡簡單單纔是真啊。順便分享一句今天寫代碼時聽到的一首歌的歌詞。

This is ten percent luck, twenty percent skill

Fifteen percent concentrated power of will

Five percent pleasure, fifty percent pain
----------------------------------------手動分割線------------------------------------

see you next illusion




發佈了32 篇原創文章 · 獲贊 6 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章