Python中defaultdict用法
认识defaultdict:
当我使用普通的字典时,用法一般是dict={},添加元素的只需要dict[element] =value即,调用的时候也是如此,dict[element] = xxx,但前提是element字典里,如果不在字典里就会报错。
defaultdict的作用是在于,当字典里的key不存在但被查找时,返回的不是keyError而是一个默认值。
如何使用defaultdict
defaultdict接受一个工厂函数作为参数,如下来构造:
dict = defaultdict( factory_function)
这个factory_function可以是list、set、str等等,作用是当key不存在时,返回的是工厂函数的默认值,比如list对应[ ],str对应的是空字符串,set对应set( ),int对应0,如下举例:
from collections import defaultdict
dict1 = defaultdict(int)
dict2 = defaultdict(set)
dict3 = defaultdict(str)
dict4 = defaultdict(list)
dict1[2] ='two'
print(dict1[1])
print(dict2[1])
print(dict3[1])
print(dict4[1])
输出:
0
set()
[]
Leetcode 207 题目描述:
Leetcode 207: https://leetcode.com/problems/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?
拓扑排序,DFS
同样是拓扑排序,但是换了个做法,使用DFS。这个方法是,我们每次找到一个新的点,判断从这个点出发是否有环。
具体做法是使用一个visited数组,当visited[i]值为0,说明还没判断这个点;当visited[i]值为1,说明当前的循环正在判断这个点;当visited[i]值为2,说明已经判断过这个点,含义是从这个点往后的所有路径都没有环,认为这个点是安全的。
那么,我们对每个点出发都做这个判断,检查这个点出发的所有路径上是否有环,如果判断过程中找到了当前的正在判断的路径,说明有环;找到了已经判断正常的点,说明往后都不可能存在环,所以认为当前的节点也是安全的。如果当前点是未知状态,那么先把当前点标记成正在访问状态,然后找后续的节点,直到找到安全的节点为止。最后如果到达了无路可走的状态,说明当前节点是安全的。
findOrder函数中的for循环是怎么回事呢?这个和BFS循环次数不是同一个概念,这里的循环就是看从第i个节点开始能否到达合理结果。这个节点可能没有出度了,那就把它直接放到path里;也可能有出度,那么就把它后面的节点都进行一次遍历,如果满足条件的节点都放到path里,同时把这次遍历的所有节点都标记成了已经遍历;如果一个节点已经被安全的访问过,那么就放过它,继续遍历下个节点。
时间复杂度是O(N ^ 2),空间复杂度是O(N)。
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
"""
input: int numCourse; List[List[int]] prerequisites;
output: boolean
"""
graph = collections.defaultdict(list)
for u, v in prerequisites:
graph[u].append(v)
# 0 = unknown, 1 = visiteing, 2 = visited
visited = [0] * numCourses
for i in range(numCourses):
if not self.dfs(graph, visited, i):
return False
return True
# can we add node i to visited successfully
def dfs(self, graph, visited, i):
if visited[i] == 1: return False
if visited[i] == 2: return True
visited[i] = 1
for j in graph[i]:
if not self.dfs(graph, visited, j):
return False
visited[i] = 2
return True
Reference
[1] https://www.jianshu.com/p/bbd258f99fd3
[2] https://blog.csdn.net/fuxuemingzhu/article/details/82951771
本文介绍了Python中的defaultdict用法,包括其如何提供默认值避免KeyError。接着讨论了LeetCode 207题目的拓扑排序问题,通过DFS方法检查课程的先决条件是否存在环,并解释了该方法的时间和空间复杂度。
919

被折叠的 条评论
为什么被折叠?



