Longest Increasing Path in Matrix
You are given a 2-D grid of integers matrix, where each integer is greater than or equal to 0.
Return the length of the longest strictly increasing path within matrix.
From each cell within the path, you can move either horizontally or vertically. You may not move diagonally.
Example 1:
Input: matrix = [[5,5,3],[2,3,6],[1,1,1]]
Output: 4
Explanation: The longest increasing path is [1, 2, 3, 6] or [1, 2, 3, 5].
Example 2:
Input: matrix = [[1,2,3],[2,1,4],[7,6,5]]
Output: 7
Explanation: The longest increasing path is [1, 2, 3, 4, 5, 6, 7].
Constraints:
1 <= matrix.length, matrix[i].length <= 100
Solution
We can use length[i][j]
to indicate the max increasing path length that ends at matrix[i][j]
. In the matrix, an element can only be added to the end if its neighbor is less than it and length[i][j]=max(length[i][j], length[NEIGHBOR]+1)
. So, if we process elements in an increasing order, we can guarantee that every possible front element has been processed before and we can get the longest length of neighbors whose value is less than current element.
Therefore, we should first sort the elements with their position, and process them in increasing order. Check the neighbors that less than current element and see whether add it to the back of the neighbor can get a longer path.
The time complexity is restricted by the sort algorithm. For bucket sort, it is O ( n × m ) O(n\times m) O(n×m); for quick sort, it is O ( n × m ⋅ log ( n × m ) ) O(n\times m\cdot \log(n\times m)) O(n×m⋅log(n×m))
Code
When we want to declare a one-dimensional list filled with 0, we can use
a = [0] * n
But if we declare a two-dimensional list filled with 0, using the code below will lead to a disaster.
a = [[0] * n] * m
We will find that when we try to modify the element at a[i][j]
, the whole a[0~n-1][j]
will change at the same time. That’s because we use *
to duplicate Mutable Data Types, a list. Actually, the different rows share the same address.
A right way to declare two-dimensional list is
a = [[0] * n] for _ in range(m)]
class Solution:
def longestIncreasingPath(self, matrix: List[List[int]]) -> int:
element_list = []
for i in range(len(matrix)):
for j in range(len(matrix[i])):
element_list.append((i, j, matrix[i][j]))
element_list.sort(key=lambda x: x[2])
length = [[1] * len(matrix[0]) for _ in range(len(matrix))]
x = [0, 0, 1,-1]
y = [1,-1, 0, 0]
ans = 0
for element in element_list:
cur_x = element[0]
cur_y = element[1]
for k in range(4):
pre_x = element[0] + x[k]
pre_y = element[1] + y[k]
if 0 <= pre_x < len(matrix) and 0 <= pre_y < len(matrix[0]):
if matrix[pre_x][pre_y] >= matrix[cur_x][cur_y]:
continue
length[cur_x][cur_y] = max(length[cur_x][cur_y], length[pre_x][pre_y]+1)
ans = max(ans, length[cur_x][cur_y])
return ans