[leetcode]高级算法——树和图

被围绕的区域

Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'.

A region is captured by flipping all 'O's into 'X's in that surrounded region.

Example:

X X X X
X O O X
X X O X
X O X X

After running your function, the board should be:

X X X X
X X X X
X X X X
X O X X

Explanation:

Surrounded regions shouldn’t be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. Two cells are connected if they are adjacent cells connected horizontally or vertically.

Code(By myself):

class Solution(object):
    def solve(self, board):
        """
        :type board: List[List[str]]
        :rtype: void Do not return anything, modify board in-place instead.
        """
        if not board:
            return
        self.row = len(board)
        self.col = len(board[0])
        for i in range(1,self.col-1):
            if board[0][i] == 'O' and board[1][i] == 'O':
                self.change(board,1,i)
            if board[self.row-1][i] == 'O' and board[self.row-2][i] == 'O':
                self.change(board,self.row-2,i)
        for i in range(1,self.row-1):
            if board[i][0] == 'O' and board[i][1] == 'O':
                self.change(board,i,1)
            if board[i][self.col-1] == 'O' and board[i][self.col-2] == 'O':
                self.change(board,i,self.col-2)
        for i in range(1,self.row-1):
            for j in range(1,self.col-1):
                if board[i][j] == 'O':
                    board[i][j] = 'X'
                elif board[i][j] == 'W':
                    board[i][j] = 'O'
        
    def change(self,board,i,j):
        board[i][j] = 'W'
        if j + 1 < self.col-1 and board[i][j+1] == 'O':
            self.change(board,i,j+1)
        if i + 1 < self.row - 1 and board[i+1][j] == 'O':
            self.change(board,i+1,j)
        if i - 1 > 0 and board[i-1][j] == 'O':
            self.change(board,i-1,j)
        if j - 1 > 0 and board[i][j-1] == 'O':
            self.change(board,i,j-1)

Code(others):

class Solution(object):
    def solve(self, board):
        """
        :type board: List[List[str]]
        :rtype: void Do not return anything, modify board in-place instead.
        """
        if not any(board):
            return

        n, m = len(board), len(board[0])
        q = [ij for k in range(max(n,m)) for ij in ((0, k), (n-1, k), (k, 0), (k, m-1))]
        while q:
            i, j = q.pop()
            if 0 <= i < n and 0 <= j < m and board[i][j] == 'O':
                board[i][j] = 'W'
                q += (i, j-1), (i, j+1), (i-1, j), (i+1, j)

        board[:] = [['XO'[c == 'W'] for c in row] for row in board]

总结:

从外围向里扩散。

二叉树的最近公共祖先

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”

Given the following binary tree:  root = [3,5,1,6,2,0,8,null,null,7,4]

Example:

        _______3______
       /              \
    ___5__          ___1__
   /      \        /      \
   6      _2       0       8
         /  \
         7   4
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of of nodes 5 and 1 is 3.

Code(By myself):

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        res = root
        if not root:
            return self.res
        res = self.find(root,p,q)[1]
        return res
    
    def find(self,root,p,q):
        if not root:
            return (0,root)
        a = self.find(root.left,p,q)
        b = self.find(root.right,p,q)
        n = a[0] + b[0]
        if a[1]:
            res = a[1]
        else:
            res = b[1]
        if root == p or root == q:
            n += 1
        if n == 2:
            res = root
            n -= 1
        return (n,res)
Code(others):
class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        if not root:
            return None
        if root==p:
            if self.searchnode(root.left,q) or self.searchnode(root.right,q):
                return root
            return None
        if root == q:
            if self.searchnode(root.left, p) or self.searchnode(root.right, p):
                return root
            return None
        if self.searchnode(p,q):
            return p
        if self.searchnode(q,p):
            return q
        pinleft=self.searchnode(root.left,p)
        pinright=not pinleft
        qinleft=self.searchnode(root.left,q)
        qinright=not qinleft
        if pinleft:
            if qinright:
                return root
            return self.lowestCommonAncestor(root.left,p,q)
        if qinleft:
            if pinright:
                return root
            return self.lowestCommonAncestor(root.left,p,q)
        return self.lowestCommonAncestor(root.right,p,q)
    def searchnode(self, root, p):
        if not root:
            return False
        if root == p:
            return True
        return self.searchnode(root.left, p) or self.searchnode(root.right, p)
class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        pathP, pathQ = self.findPath(root, p), self.findPath(root, q)
        lenP, lenQ = len(pathP), len(pathQ)
        ans, x = None, 0
        while x < min(lenP, lenQ) and pathP[x] == pathQ[x]:
            ans, x = pathP[x], x + 1
        return ans
        
    def findPath(self, root, target):
        stack = []
        lastVisit = None
        while stack or root:
            if root:
                stack.append(root)
                root = root.left
            else:
                peek = stack[-1]
                if peek.right and lastVisit != peek.right:
                    root = peek.right
                else:
                    if peek == target:
                        return stack
                    lastVisit = stack.pop()
                    root = None
        return stack
class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        if root in (None,q,p):
            return root
        if self.isParent(p,q):
            return p
        if self.isParent(q,p):
            return q
        while root:
            if self.isParent(root.left,p) and self.isParent(root.left,q):
                root=root.left
            elif self.isParent(root.right,p) and self.isParent(root.right,q):
                root=root.right
            else:
                return root
        return root
    def isParent(self,p,q):
        if not p:
            return False
        if p==q:
            return True
        return self.isParent(p.left,q) or self.isParent(p.right,q)

总结:

  • 判断p,q是否都在左子树或者都在右子树,若在两边,则该节点就是最近祖先
  • 将从根节点到p和q的路径分别记录下来,同时遍历,两者不同之前最后一个节点就是最近祖先

二叉树中的最大路径和

Given a non-empty binary tree, find the maximum path sum.

For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root.

Example:

Input: [1,2,3]

       1
      / \
     2   3

Output: 6

Code(By myself):

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    
    def maxPathSum(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        self.treePathLen = []
        res = self.pathSum(root)
        return max(self.treePathLen)
    
    def pathSum(self,root):
        if not root:
            return -float('inf')
        leftLen = self.pathSum(root.left)
        rightLen = self.pathSum(root.right)
        if leftLen == -float('inf') and rightLen == -float('inf'):
            treeLen = root.val
        elif leftLen == -float('inf'):
            treeLen = root.val + rightLen
        elif rightLen == -float('inf'):
            treeLen = root.val + leftLen
        else:
            treeLen = root.val + leftLen + rightLen
        maxTreeLen = max(treeLen,leftLen,rightLen,root.val,max(leftLen,rightLen) + root.val)
        self.treePathLen.append(maxTreeLen)
        return max(max(leftLen,rightLen) + root.val, root.val)
Code(others):
class Solution(object):
    maxVal = 0
    def maxPathSum(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        global maxVal
        maxVal = root.val
        def maxSum(r):
            if(r == None):
                return 0
            curVal = r.val
            lmaxSum = maxSum(r.left)
            rmaxSum = maxSum(r.right)
            if(lmaxSum > 0):
                curVal += lmaxSum
            if(rmaxSum > 0):
                curVal += rmaxSum
            global maxVal
            if(curVal > maxVal):
                maxVal = curVal
            
            return max(r.val, r.val + lmaxSum, r.val + rmaxSum)
        maxSum(root)
        return maxVal

总结:

  • 递归求解,每部都返回节点值、节点值加左子树能到达根节点最长的路径和,节点值加右子树能到达根节点最长的路径和三者最大,全局变量更新子树的最大路径和。
  • 思想类似,代码能力差距太大,理清思路在写代码

Friends circles

There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a directfriend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends.

Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students.

Example:

Input: 
[[1,1,0],
 [1,1,0],
 [0,0,1]]
Output: 2
Explanation:The 0th and 1st students are direct friends, so they are in a friend circle. 
The 2nd student himself is in a friend circle. So return 2.

Code(By myself):

class Solution(object):
    def findCircleNum(self, M):
        """
        :type M: List[List[int]]
        :rtype: int
        """
        row = len(M)
        count = 0
        mark = [True for i in range(row)]
        for i in range(row):
            if mark[i]:
                self.dfs(M,mark,i)
                count += 1
        return count
    
    def dfs(self,M,mark,i):
        mark[i] = False
        for j in range(len(M[0])):
            if mark[j] and M[i][j] == 1:
                self.dfs(M,mark,j)
Code(others):
class Solution(object):
    def findCircleNum(self, M):
        """
        :type M: List[List[int]]
        :rtype: int
        """
        
        if M ==[] or len(M)==0 or len(M[0])!=len(M):
            return 0
        
        ans = 0
        rest = list(range(len(M)))
        while rest:
            stack = [rest.pop(0)]
            while stack:
                cur = stack.pop()
                for x in [x for x in rest if M[cur][x]]:
                    rest.remove(x)
                    stack.append(x)
            ans += 1
        return ans

总结:

  • 问题本质上是求无向图的连通分量的数量
  • 可用dfs和kahn两种算法求解,详细见https://blog.csdn.net/qinzhaokun/article/details/48541117

课程表Ⅰ

There are a total of n courses you have to take, labeled from 0 to n-1.

Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

Example:

Input: 2, [[1,0]] 
Output: true
Explanation: There are a total of 2 courses to take. 
             To take course 1 you should have finished course 0. So it is possible.

Code(By myself):

class Solution(object):
    def canFinish(self, numCourses, prerequisites):
        """
        :type numCourses: int
        :type prerequisites: List[List[int]]
        :rtype: bool
        """
        inDegree = [0 for i in range(numCourses)]
        dic = {}
        for i in prerequisites:
            inDegree[i[0]] += 1
            if i[1] not in dic:
                dic[i[1]] = [i[0]]
            else:
                dic[i[1]].append(i[0])
        stack = []
        n = 0
        for i in range(numCourses):
            if inDegree[i] == 0:
                stack.append(i)
        while stack:
            cur = stack.pop(0)
            n += 1
            if cur in dic:
                for i in dic[cur]:
                    inDegree[i] -= 1
                    if inDegree[i] == 0:
                        stack.append(i)
        if n == numCourses:
            return True
        else:
            return False
Code(others):
class Solution(object):
    def canFinish(self, n, pres):
        """
        :type numCourses: int
        :type prerequisites: List[List[int]]
        :rtype: bool
        """
        from collections import deque
        ind = [[] for _ in xrange(n)]  # indegree
        oud = [0] * n  # outdegree
        for p in pres:
            oud[p[0]] += 1
            ind[p[1]].append(p[0])
        dq = deque()
        for i in xrange(n):
            if oud[i] == 0:
                dq.append(i)
        k = 0
        while dq:
            x = dq.popleft()
            k += 1
            for i in ind[x]:
                oud[i] -= 1
                if oud[i] == 0:
                    dq.append(i)
        return k == n
class Solution:
    def canFinish(self, numCourses, prerequisites):
        graph = [[] for _ in range(numCourses)]
        visit = [0 for _ in range(numCourses)]
        for x, y in prerequisites:
            graph[x].append(y)  # 生成每门课的全部先修课程列表,角标为当前课,内容为先修课程列表
        def dfs(i):
            if visit[i] == -1:  
                return False
            if visit[i] == 1:
                return True
            visit[i] = -1
            for j in graph[i]:  # 循环检查所有先修课程的所有先修课程,有没有指向后修课程的,即为-1的
                if not dfs(j):
                    return False
            visit[i] = 1
            return True
        for i in range(numCourses):  # 遍历每一门课,检查先修课程以及先修课程的先修课程。。。有没有环
            if not dfs(i):
                return False
        return True

总结:

  • 本题本质上是判断有向图中是否存在环
  • 可用dfs和kahn两种算法求解,详细见https://blog.csdn.net/qinzhaokun/article/details/48541117

课程表Ⅱ

There are a total of n courses you have to take, labeled from 0 to n-1.

Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.

There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.

Example:

Input: 2, [[1,0]] 
Output: [0,1]
Explanation: There are a total of 2 courses to take. To take course 1 you should have finished   
             course 0. So the correct course order is [0,1] .

Code(By myself):

class Solution(object):
    def findOrder(self, numCourses, prerequisites):
        """
        :type numCourses: int
        :type prerequisites: List[List[int]]
        :rtype: List[int]
        """
        visit = [0 for i in range(numCourses)]
        graph = [[] for i in range(numCourses)]
        res = []
        for i in prerequisites:
            graph[i[0]].append(i[1])
        def dfs(i):
            if visit[i] == -1:
                return False
            elif visit[i] == 1:
                return True
            visit[i] = -1
            for j in graph[i]:
                if not dfs(j):
                    return False
            visit[i] = 1
            res.append(i)
            return True
        for i in range(numCourses):
            if not dfs(i):
                return []
        return res
Code(others):
class Solution(object):
    def findOrder(self, numCourses, prerequisites):
        """
        :type numCourses: int
        :type prerequisites: List[List[int]]
        :rtype: List[int]
        """
        graph = [[] for _ in xrange(numCourses)]
        ins = [0 for _ in xrange(numCourses)] 
        for a in prerequisites:
            graph[a[1]].append(a[0])
            ins[a[0]] += 1
        q = []
        for i in xrange(numCourses):
            if ins[i] == 0:
                q.append(i)
        res = []
        while len(q) > 0:
            t = q.pop(0)
            res.append(t)
            for a in graph[t]:
                ins[a] -= 1
                if ins[a] == 0:
                    q.append(a)
        return res if len(res) == numCourses else []

class Solution(object):
    def findOrder(self, numCourses, prerequisites):
        """
        :type numCourses: int
        :type prerequisites: List[List[int]]
        :rtype: List[int]
        """
        graph = [[] for _ in range(numCourses)]
        level = [0 for _ in range(numCourses)]
        visit = [0 for _ in range(numCourses)]
        for x, y in prerequisites:
            graph[x].append(y)  # 生成每门课的全部先修课程列表,角标为当前课,内容为先修课程列表
        def dfs(i):
            _max = level[i]
            if visit[i] == -1:
                return False, _max
            if visit[i] == 1:
                return True, _max
            visit[i] = -1
            for j in graph[i]:  # 循环检查所有先修课程的所有先修课程,有没有指向后修课程的,即为-1的
                flag, _level = dfs(j)
                if not flag:
                    return False, _max
                _max = max(_max, _level+1)
            level[i] = _max
            visit[i] = 1
            return True, _max
        for i in range(numCourses):  # 遍历每一门课,检查先修课程以及先修课程的先修课程。。。有没有环
            flag, _level = dfs(i)
            if not flag:
                return []
        res = {}
        for k, v in enumerate(level):
            if v not in res:
                res[v] = []
            res[v].append(k)
        ret = []
        i = 0
        while True:
            if i in res:
                ret += res[i]
                i += 1
            else:
                break
        return ret

总结:

  • 本题本质上是求有向图的拓扑序列
  • 可用dfs和kahn两种算法求解,详细见https://blog.csdn.net/qinzhaokun/article/details/48541117

计算右侧小于当前元素的个数

You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].

Example:

Input: [5,2,6,1]
Output: [2,1,1,0] 
Explanation:
To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.

Code(By myself):

class Solution(object):
    def countSmaller(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        if not nums:
            return nums
        n = len(nums)
        counts = [0 for i in range(n)]
        temp = [nums[n-1]]
        for i in range(n-2,-1,-1):
            left = 0
            right = len(temp)
            while left < right:
                mid = (left + right) // 2
                if temp[mid] < nums[i]:
                    left = mid + 1
                else:
                    right = mid
            counts[i] = left
            temp.insert(left,nums[i])
        return counts
Code(others):
class BinaryIndexedTree(object):
    def __init__(self, n):
        self.sums = [0] * (n + 1)

    def update(self, i, val):
        while i < len(self.sums):
            self.sums[i] += 1
            i += i & -i

    def sum(self, i):
        r = 0
        while i > 0:
            r += self.sums[i]
            i -= i & -i
        return r


class Solution(object):
    def countSmaller(self, nums):
        hashTable = {v: i for i, v in enumerate(sorted(set(nums)))}

        tree, r = BinaryIndexedTree(len(hashTable)), []
        for i in xrange(len(nums) - 1, -1, -1):
            r.append(tree.sum(hashTable[nums[i]]))
            tree.update(hashTable[nums[i]] + 1, 1)
        return r[::-1]
class Solution:
    def countSmaller(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        tmp = []
        ans = []
        for i in nums[::-1]:
            x = bisect.bisect_left(tmp, i)
            ans.append(x)
            tmp.insert(x, i)
        
        return ans[::-1]

总结:

  • 利用双层循环时间复杂度为O(n²),不满足时间要求,则插入采取二分查找后插入,时间复杂度为O(n²)顺利通过。

单词接龙

Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:

  1. Only one letter can be changed at a time.
  2. Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

Note:

  • Return 0 if there is no such transformation sequence.
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
  • You may assume no duplicates in the word list.
  • You may assume beginWord and endWord are non-empty and are not the same.

Example:

Input:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

Output: 5

Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.

Code(By myself):

import string
class Solution(object):
    def ladderLength(self, beginWord, endWord, wordList):
        """
        :type beginWord: str
        :type endWord: str
        :type wordList: List[str]
        :rtype: int
        """
        if endWord not in wordList:
            return 0
        queue = [beginWord]
        n = len(beginWord)
        wordDic = {}
        for i in wordList:
            if i not in wordDic:
                wordDic[i] = 1
        lowercase = [i for i in string.lowercase]
        dic = {}
        dic[beginWord] = 1
        while queue:
            cur = queue.pop(0)
            for i in range(n):
                for j in lowercase:
                    temp = cur
                    if temp[i] == j:
                        continue
                    else:
                        temp = temp[:i] + j + temp[i+1:]
                    if temp == endWord:
                        return dic[cur] + 1
                    if temp in wordDic and temp not in dic:
                        queue.append(temp)
                        dic[temp] = dic[cur] + 1
        if endWord  not in dic:
            return 0
        return dic[endWord]
Code(others):
class Solution(object):
    def ladderLength(self, beginWord, endWord, wordList):
        if endWord not in wordList:
            return 0

        wordList = set(wordList)
        forward, backward, n, cnt = {beginWord}, {endWord}, len(beginWord), 2
        dic = set(string.ascii_lowercase)

        while len(forward) > 0 and len(backward) > 0:
            if len(forward) > len(backward): # 加速
                forward, backward = backward, forward

            next = set()
            for word in forward:
                for i, char in enumerate(word):
                    first, second = word[:i], word[i + 1:]
                    for c in dic: # 遍历26个字母
                        candidate = first + c + second
                        if candidate in backward: # 如果找到了,返回结果,没有找到,则在wordList中继续寻找
                            return cnt

                        if candidate in wordList:
                            wordList.discard(candidate) # 从wordList中去掉单词
                            next.add(candidate) #加入下一轮的bfs中
            forward = next
            cnt += 1
        return 0

总结:

  • 利用广度优先搜索BFS算法,队列可以实现,每次找到最接近的,相当于树的层次遍历。

矩阵中最长的递增路径

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:

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

Code(By myself):

class Solution(object):
    def longestIncreasingPath(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: int
        """
        maxPathLen = 0
        if not matrix:
            return maxPathLen
        row = len(matrix)
        col = len(matrix[0])
        path = [(1,0),(-1,0),(0,1),(0,-1)]
        maxPath = [[-1 for j in range(col)] for i in range(row)]
        def increasingPath(matrix,i,j,pre):
            n = 0
            if i < 0 or i >= row or j < 0 or j >= col:
                return n
            if matrix[i][j] > pre:
                if maxPath[i][j] >= 0:
                    return maxPath[i][j]
                for temp in path:
                    n = max(n, increasingPath(matrix, i + temp[0], j + temp[1], matrix[i][j]) + 1)
                maxPath[i][j] = max(maxPath[i][j],n)
            return n
            
        for i in range(row):
            for j in range(col):
                m = 0
                for k in path:
                    m = max(m, increasingPath(matrix, i + k[0], j + k[1], matrix[i][j]) + 1)
                maxPath[i][j] = max(maxPath[i][j],m)
                maxPathLen = max(maxPathLen, m)
        return maxPathLen
Code(others):
class Solution(object):
    def longestIncreasingPath(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: int
        """
        if not matrix or not matrix[0]:
            return 0
        m = len(matrix)
        n = len(matrix[0])
        memo = [[0] * n for i in range(m)]
        def helper(i, j):
            if not memo[i][j]:
                ans = 0
                num = matrix[i][j]
                if i > 0 and matrix[i-1][j] > num:
                    ans = max(ans, helper(i-1, j))
                if j > 0 and matrix[i][j-1] > num:
                    ans = max(ans, helper(i, j-1))
                if i < m - 1 and matrix[i+1][j] > num:
                    ans = max(ans, helper(i+1, j))
                if j < n - 1 and matrix[i][j+1] > num:
                    ans = max(ans, helper(i, j+1))
                memo[i][j] = ans + 1
            return memo[i][j]
        ans = 0
        for i in range(m):
            for j in range(n):
                ans = max(ans, helper(i, j))
        return ans

总结:

  • 在寻找最长路径的过程中,在新建的一个二维表中记录每个计算过的点的最长递增路径
  • 优化代码



你可能感兴趣的:(python,leetcode)