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




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值