算法设计与分析--动态规划(八)

39 篇文章 0 订阅
10 篇文章 0 订阅

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:

Input: nums =
[
[9,9,4],
[6,6,8],
[2,1,1]
]
Output: 4
Explanation: The longest increasing path is [1, 2, 6, 9].
Example 2:

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

分析

首先,看到这个题目,我们会有一种似曾相识的感觉,这种感觉来源与求最长子序列这道题目,这道题目是动态规划的经典题目了。但这道题目与求最长子序列有点差别,首先,动态规划求最长子序列处理的是数组,这里处理的是矩阵。同时,数组遍历计算的方向只有一个,那就是往下标递增的顺序计算,而矩阵不同,对于非边界的元素,其计算的方向可以是上下左右四个方向。第二,经典的最长子序列求法是对于不连续递增的元素的,但这里递增的元素需要是连续相邻的位置的。
上面说到的差别应用在我们的实现中,具体表现为通过对矩阵遍历,求出每个点,也就是子问题的连续最长子序列,然后求另外点的最长子序列时用到已经求得的子问题的答案。也就是子问题加上1,就是下一个子问题的答案。
注意一点是,在矩阵下标没有越界的情况下,一个元素的四个方向都有可能有子问题,所以在遍历每个点的时候,都需要检查四个方向,对比四个方向子问题合成的当前问题的最优解。
这个过程与深度遍历有点类似,但一个明显的不同是,这里的动态规划算法保存了子问题的解,在需要利用都子问题的时候,从已经存有的子问题中找出答案即可,无需遍历做多无用的工。

源码

class Solution {
public:
	int dfs(vector<vector<int>>& matrix, int row, int col, vector<vector<int> > &dp) {
		if(dp[row][col] != 0) {
			return dp[row][col];
		}
		int beginResult = 1;
		int a[4] = {-1, 1, 0, 0};
		int b[4] = {0, 0, -1, 1};

		for(int i = 0; i < 4; i++) {
			int currX = row + a[i];
			int currY = col + b[i];
			if(currX >= 0&&currX < matrix.size()&&currY >= 0&&currY < matrix[0].size()&&matrix[currX][currY] > matrix[row][col]) {
				beginResult = max(beginResult, 1 + dfs(matrix, currX, currY, dp));
			}
		}
		dp[row][col] = beginResult;
		return dp[row][col];
	}

    int longestIncreasingPath(vector<vector<int>>& matrix) {
    	if(matrix.size() == 0||matrix[0].size() == 0) {
        	return 0;
        }
    	int result = 0;
    	vector<vector<int> > dp(matrix.size(), vector<int>(matrix[0].size(), 0));
        for(int i = 0; i < matrix.size(); i++) {
        	for(int j = 0; j < matrix[0].size(); j++) {
        		result = max(result, dfs(matrix, i, j, dp));
        	}
        }
        return result;
    }
};

感悟

这个是动态规划经典例题的证明,对于能用其他方法解决的问题,如果能用动态规划来解决,解决的方案一般是比较佳的。但问题是动态规划比较难,变化非常多。其有两种基本的变形,第一种是自顶向下的,另外一种是自底向上的。这个问题是自顶向下的比较经典的问题,一般是采用递归解决,但这里的递归比一般的递归效率更高。

更多技术博客https://vilin.club/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值