207. Course 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:
- The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
- 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
210. Course 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:
- The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
- You may assume that there are no duplicate edges in the input prerequisites.
题意大体与207一致,不过要输出课程的正确顺序。
1.利用深度优先判断该门课是否能够进行,存在一门课无法进行,那么课程的顺序将为空;
2.利用栈,判断出该门课所在的位置
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
329. 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:
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
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))