【LeetCode编程小结】Topological Sort

207Course Schedule

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?

For example:

2, [[1,0]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.

2, [[1,0],[0,1]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.

Note:

  1. The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
  2. You may assume that there are no duplicate edges in the input prerequisites.

题意:

一共有N门课,标签从0~N-1,一些课有先决条件,比如上课0前要上课1,表达式为【0,1】

思路:

先决条件可以表示图,可以通过深度优先的方式判断一门课的先决条件能够满足要求,借助一维数组保存该门课能否完成的状态,减少再次判断同一门课的深度遍历

Code:

class Solution:
    def canFinish(self, numCourses, prerequisites):
        """
        :type numCourses: int
        :type prerequisites: List[List[int]]
        :rtype: bool
        """
        def dp(gra,index,visit,canf):#深度优先函数

        	visit.append(index)#保存访问的记录
        	if canf[index] == 1:#如果该门课已经判定过能够进行,直接返回True
        		return True
        	for i in range(numCourses):#对该门课每一个先决条件进行判断
        		if grap[index][i] == 1:
        			if i in visit:#如果该门课在已经访问过,则说明图中出现环,False
        				return False
        			if not dp(grap,i,visit[:],canf):
        				return False
        			else:
        				canf[i] = 1
        	return True
        grap = [[-1]*numCourses for i in range(numCourses)]#初始化图
        for line in prerequisites:
        	grap[line[0]][line[1]] =1#存储先决条件
        canf = [-1]* numCourses #保存每门课的状态
        for i in range(numCourses):
        	if canf[i] == 1:
        		continue
        	if not dp(grap,i,[],canf):
        		return False
        	else:
        		canf[i] =1
        return True

210Course Schedule II

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.

For example:

2, [[1,0]]

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]

4, [[1,0],[2,0],[3,1],[3,2]]

There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering is[0,2,1,3].

Note:

  1. The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
  2. You may assume that there are no duplicate edges in the input prerequisites.
题意:

题意大体与207一致,不过要输出课程的正确顺序。

思路:

1.利用深度优先判断该门课是否能够进行,存在一门课无法进行,那么课程的顺序将为空;

2.利用栈,判断出该门课所在的位置

Code:
class Solution:
    def findOrder(self, numCourses, prerequisites):
        """
        :type numCourses: int
        :type prerequisites: List[List[int]]
        :rtype: List[int]
        """
        result = [] #课程顺序list
        def dp(gra,index,visit,canf):
        	stack = [] #存储该课的先决条件
        	visit.append(index) #存储访问历史
        	if canf[index] == 1: #如果该门课可完成,直接返回True
        		return True
        	for i in range(numCourses):
        		if grap[index][i] == 1:
        			if i in visit:
        				return False
        			if not dp(grap,i,visit[:],canf):
        				return False
        			else:
        				stack.append(i) #将可完成的先决条件入栈
        				canf[i] = 1
        	if len(result) == 0:#如果该课是第一门课,直接放入队列中
        		result.append(index)
        	else:
        		maxin = 0
        		while  len(stack)!=0:
        			maxin = max(maxin,result.index(stack[-1])) #找到最后一门先决条件的位置
        			stack.pop(-1)
        		result.insert(maxin+1,index) #将课程插入到正确的位置
        	return True
        grap = [[-1]*numCourses for i in range(numCourses)]
        for line in prerequisites:
        	grap[line[0]][line[1]] =1
        canf = [-1]* numCourses
        for i in range(numCourses):
        	if canf[i] == 1:
        		continue
        	if not dp(grap,i,[],canf):
        		return []
        	else:
        		canf[i] =1

        return result

329Longest 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.

题意:
给定整型矩阵,找到最长递增部分的长度。对于每一个格,只有四个移动方向,上,下,左,右,每次只能移动一个位置,并且不能移到边界外。
思路:

利用深度优先的方法,判断其四周最长的递增,再加上1

Code:
class Solution:
    def longestIncreasingPath(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: int
        """
        if not matrix or not matrix[0]:
        	return 0
        else:
        	H,W = len(matrix),len(matrix[0])
        	dp = [[0]*W for i in range(H)]
        	def dfs(i,j):
        		if not dp[i][j]:
        			val = matrix[i][j]
        			dp[i][j] = 1+max(
        				dfs(i-1,j) if i-1 >=0 and matrix[i-1][j]> val else 0,
        				dfs(i+1,j) if i+1 < H and matrix[i+1][j]>val else 0,
        				dfs(i,j-1) if j-1>=0 and matrix[i][j-1]> val else 0,
        				dfs(i,j+1) if j+1 < W and matrix[i][j+1]>val else 0)
        		return dp[i][j]
        	return max(dfs(i,j) for i in range(H) for j in range(W))
        

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值