使用记忆化深度优先搜索
<?php
class Solution {
private $dir = [
[0,1],
[0,-1],
[1,0],
[-1,0],
];
// 用于记录已经搜索过的点的最大路径值
private $path = [];
private $rCnt;
private $cCnt;
/**
* @param Integer[][] $matrix
* @return Integer
*/
function longestIncreasingPath($matrix) {
$this->rCnt = count($matrix);
if ($this->rCnt == 0) {
return 0;
}
$this->cCnt = count($matrix[0]);
if ($this->cCnt == 0) {
return 0;
}
$this->path = array_fill(0, $this->rCnt*$this->cCnt, 0);
$ans = 1;
foreach ($matrix as $rIdx => $rowData) {
foreach ($rowData as $cIdx => $cellData) {
$pathLen = $this->findLongestPath($matrix, $rIdx, $cIdx);
$ans = max($ans, $pathLen);
}
}
return $ans;
}
function findLongestPath(&$matrix, $rIdx, $cIdx) {
$idx = $rIdx * $this->cCnt + $cIdx;
if ($this->path[$idx] != 0) {
return $this->path[$idx];
}
$tmpMax = 0;
foreach ($this->dir as $dir) {
$newR = $rIdx+$dir[0];
$newC = $cIdx+$dir[1];
if ($newR>=0 && $newR<$this->rCnt && $newC>=0 && $newC<$this->cCnt
&& $matrix[$newR][$newC] > $matrix[$rIdx][$cIdx]) {
$curLen = $this->findLongestPath($matrix, $newR, $newC);
$tmpMax = max($curLen, $tmpMax);
}
}
$this->path[$idx] = $tmpMax + 1;
return $tmpMax + 1;
}
}
结果
新增一种解法:动态规划+拓扑排序
class Solution {
private $dir = [
[0,1],
[0,-1],
[1,0],
[-1,0],
];
/**
* @param Integer[][] $matrix
* @return Integer
*/
function longestIncreasingPath($matrix) {
$rCnt = count($matrix);
if ($rCnt == 0) {
return 0;
}
$cCnt = count($matrix[0]);
if ($cCnt == 0) {
return 0;
}
$outDegrees = [];
foreach ($matrix as $rIdx => $rowData) {
foreach ($rowData as $cIdx => $cellData) {
$idx = $rIdx*$cCnt+$cIdx;
$outDegrees[$idx] = 0;
foreach ($this->dir as $dir) {
$newR = $rIdx+$dir[0];
$newC = $cIdx+$dir[1];
if ($newR>=0 && $newR<$rCnt && $newC>=0 && $newC<$cCnt
&& $matrix[$newR][$newC] > $matrix[$rIdx][$cIdx]) {
$outDegrees[$idx]++;
}
}
}
}
$queue = new SplQueue();
foreach ($outDegrees as $k => $degree) {
if ($degree == 0) {
$queue->enqueue($k);
}
}
$ans = 0;
while(!$queue->isEmpty()) {
$ans++;
$size = $queue->count();
while ($size-- > 0) {
$idx = $queue->dequeue();
$rIdx = intdiv($idx, $cCnt);
$cIdx = $idx % $cCnt;
foreach ($this->dir as $dir) {
$newR = $rIdx+$dir[0];
$newC = $cIdx+$dir[1];
if ($newR>=0 && $newR<$rCnt && $newC>=0 && $newC<$cCnt
&& $matrix[$newR][$newC] < $matrix[$rIdx][$cIdx]) {
$newIdx = $newR*$cCnt+$newC;
if (--$outDegrees[$newIdx]==0) {
$queue->enqueue($newIdx);
}
}
}
}
}
return $ans;
}
}
结果: