classSolution{public:boolcanFinish(int n, vector<vector<int>>& edges){
vector<vector<int>>g(n);
vector<int>d(n);for(auto& e: edges){int b = e[0], a = e[1];
g[a].push_back(b);
d[b]++;}
queue<int> q;for(int i =0; i < n; i ++)if(d[i]==0)
q.push(i);int cnt =0;while(q.size()){auto t = q.front();
q.pop();
cnt ++;for(auto i : g[t])if(-- d[i]==0)
q.push(i);}return cnt == n;}};
classSolution{
List<List<Integer>> edges;int[] visited;boolean valid =true;publicbooleancanFinish(int numCourses,int[][] prerequisites){
edges =newArrayList<List<Integer>>();for(int i =0; i < numCourses;++i){
edges.add(newArrayList<Integer>());}
visited =newint[numCourses];for(int[] info : prerequisites){
edges.get(info[1]).add(info[0]);}for(int i =0; i < numCourses && valid;++i){if(visited[i]==0){dfs(i);}}return valid;}publicvoiddfs(int u){
visited[u]=1;for(int v: edges.get(u)){if(visited[v]==0){dfs(v);if(!valid){return;}}elseif(visited[v]==1){
valid =false;return;}}
visited[u]=2;}}
classSolution:defcanFinish(self, numCourses:int, prerequisites: List[List[int]])->bool:
edges = collections.defaultdict(list)
visited =[0]* numCourses
result =list()
valid =Truefor info in prerequisites:
edges[info[1]].append(info[0])defdfs(u:int):nonlocal valid
visited[u]=1for v in edges[u]:if visited[v]==0:
dfs(v)ifnot valid:returnelif visited[v]==1:
valid =Falsereturn
visited[u]=2
result.append(u)for i inrange(numCourses):if valid andnot visited[i]:
dfs(i)return valid
funccanFinish(numCourses int, prerequisites [][]int)bool{var(
edges =make([][]int, numCourses)
visited =make([]int, numCourses)
result []int
valid =true
dfs func(u int))
dfs =func(u int){
visited[u]=1for_, v :=range edges[u]{if visited[v]==0{dfs(v)if!valid {return}}elseif visited[v]==1{
valid =falsereturn}}
visited[u]=2
result =append(result, u)}for_, info :=range prerequisites {
edges[info[1]]=append(edges[info[1]], info[0])}for i :=0; i < numCourses && valid; i++{if visited[i]==0{dfs(i)}}return valid
}
第二百零八题:
classTrie{public:struct Node {bool is_end;
Node *son[26];Node(){
is_end =false;for(int i =0; i <26; i ++)
son[i]=NULL;}}*root;/** Initialize your data structure here. */Trie(){
root =newNode();}/** Inserts a word into the trie. */voidinsert(string word){auto p = root;for(auto c: word){int u = c -'a';if(!p->son[u]) p->son[u]=newNode();
p = p->son[u];}
p->is_end =true;}/** Returns if the word is in the trie. */boolsearch(string word){auto p = root;for(auto c: word){int u = c -'a';if(!p->son[u])returnfalse;
p = p->son[u];}return p->is_end;}/** Returns if there is any word in the trie that starts with the given prefix. */boolstartsWith(string word){auto p = root;for(auto c: word){int u = c -'a';if(!p->son[u])returnfalse;
p = p->son[u];}returntrue;}};/**
* Your Trie object will be instantiated and called as such:
* Trie* obj = new Trie();
* obj->insert(word);
* bool param_2 = obj->search(word);
* bool param_3 = obj->startsWith(prefix);
*/
classTrie{private TrieNode root;publicTrie(){
root =newTrieNode();}// Inserts a word into the trie.publicvoidinsert(String word){
TrieNode node = root;for(int i =0; i < word.length(); i++){char currentChar = word.charAt(i);if(!node.containsKey(currentChar)){
node.put(currentChar,newTrieNode());}
node = node.get(currentChar);}
node.setEnd();}}
classTrie:def__init__(self):"""
Initialize your data structure here.
"""
self.lookup ={}definsert(self, word:str)->None:"""
Inserts a word into the trie.
"""
tree = self.lookup
for a in word:if a notin tree:
tree[a]={}
tree = tree[a]# 单词结束标志
tree["#"]="#"defsearch(self, word:str)->bool:"""
Returns if the word is in the trie.
"""
tree = self.lookup
for a in word:if a notin tree:returnFalse
tree = tree[a]if"#"in tree:returnTruereturnFalsedefstartsWith(self, prefix:str)->bool:"""
Returns if there is any word in the trie that starts with the given prefix.
"""
tree = self.lookup
for a in prefix:if a notin tree:returnFalse
tree = tree[a]returnTrue
type Trie struct{
next [26]*Trie
isEnd bool}/** Initialize your data structure here. */funcConstructor() Trie {return Trie{}}/** Inserts a word into the trie. */func(this *Trie)Insert(word string){
node := this
for_, v :=range word {
v -='a'if node.next[v]==nil{
node.next[v]=&Trie{}}
node = node.next[v]}
node.isEnd =true}/** Returns if the word is in the trie. */func(this *Trie)Search(word string)bool{
node := this
for_, v :=range word {if node = node.next[v-'a']; node ==nil{returnfalse}}return node.isEnd
}/** Returns if there is any word in the trie that starts with the given prefix. */func(this *Trie)StartsWith(prefix string)bool{
node := this
for_, v :=range prefix {if node = node.next[v-'a']; node ==nil{returnfalse}}returntrue}
第二百零九题:
classSolution{public:intminSubArrayLen(int s, vector<int>& nums){int res = INT_MAX;for(int i =0, j =0, sum =0; i < nums.size(); i ++){
sum += nums[i];while(sum - nums[j]>= s) sum -= nums[j ++];if(sum >= s) res =min(res, i - j +1);}if(res == INT_MAX) res =0;return res;}};
classSolution{publicintminSubArrayLen(int s,int[] nums){int n = nums.length;if(n ==0){return0;}int ans = Integer.MAX_VALUE;int[] sums =newint[n +1];// 为了方便计算,令 size = n + 1 // sums[0] = 0 意味着前 0 个元素的前缀和为 0// sums[1] = A[0] 前 1 个元素的前缀和为 A[0]// 以此类推for(int i =1; i <= n; i++){
sums[i]= sums[i -1]+ nums[i -1];}for(int i =1; i <= n; i++){int target = s + sums[i -1];int bound = Arrays.binarySearch(sums, target);if(bound <0){
bound =-bound -1;}if(bound <= n){
ans = Math.min(ans, bound -(i -1));}}return ans == Integer.MAX_VALUE ?0: ans;}}
classSolution:defminSubArrayLen(self, s:int, nums: List[int])->int:ifnot nums:return0
n =len(nums)
ans = n +1
sums =[0]for i inrange(n):
sums.append(sums[-1]+ nums[i])for i inrange(1, n +1):
target = s + sums[i -1]
bound = bisect.bisect_left(sums, target)if bound !=len(sums):
ans =min(ans, bound -(i -1))return0if ans == n +1else ans
funcminSubArrayLen(s int, nums []int)int{
n :=len(nums)if n ==0{return0}
ans := math.MaxInt32
sums :=make([]int, n +1)// 为了方便计算,令 size = n + 1 // sums[0] = 0 意味着前 0 个元素的前缀和为 0// sums[1] = A[0] 前 1 个元素的前缀和为 A[0]// 以此类推for i :=1; i <= n; i++{
sums[i]= sums[i -1]+ nums[i -1]}for i :=1; i <= n; i++{
target := s + sums[i-1]
bound := sort.SearchInts(sums, target)if bound <0{
bound =-bound -1}if bound <= n {
ans =min(ans, bound -(i -1))}}if ans == math.MaxInt32 {return0}return ans
}funcmin(x, y int)int{if x < y {return x
}return y
}
第二百一十题:
classSolution{public:
vector<int>findOrder(int n, vector<vector<int>>& edges){
vector<vector<int>>g(n);
vector<int>d(n);for(auto& e: edges){int b = e[0], a = e[1];
g[a].push_back(b);
d[b]++;}
queue<int> q;for(int i =0; i < n; i ++)if(d[i]==0)
q.push(i);
vector<int> res;while(q.size()){auto t = q.front();
q.pop();
res.push_back(t);for(int i: g[t])if(-- d[i]==0)
q.push(i);}if(res.size()< n) res ={};return res;}};
classSolution{// 存储有向图
List<List<Integer>> edges;// 标记每个节点的状态:0=未搜索,1=搜索中,2=已完成int[] visited;// 用数组来模拟栈,下标 n-1 为栈底,0 为栈顶int[] result;// 判断有向图中是否有环boolean valid =true;// 栈下标int index;publicint[]findOrder(int numCourses,int[][] prerequisites){
edges =newArrayList<List<Integer>>();for(int i =0; i < numCourses;++i){
edges.add(newArrayList<Integer>());}
visited =newint[numCourses];
result =newint[numCourses];
index = numCourses -1;for(int[] info : prerequisites){
edges.get(info[1]).add(info[0]);}// 每次挑选一个「未搜索」的节点,开始进行深度优先搜索for(int i =0; i < numCourses && valid;++i){if(visited[i]==0){dfs(i);}}if(!valid){returnnewint[0];}// 如果没有环,那么就有拓扑排序return result;}publicvoiddfs(int u){// 将节点标记为「搜索中」
visited[u]=1;// 搜索其相邻节点// 只要发现有环,立刻停止搜索for(int v: edges.get(u)){// 如果「未搜索」那么搜索相邻节点if(visited[v]==0){dfs(v);if(!valid){return;}}// 如果「搜索中」说明找到了环elseif(visited[v]==1){
valid =false;return;}}// 将节点标记为「已完成」
visited[u]=2;// 将节点入栈
result[index--]= u;}}
funcfindOrder(numCourses int, prerequisites [][]int)[]int{var(
edges =make([][]int, numCourses)
visited =make([]int, numCourses)
result []int
valid bool=true
dfs func(u int))
dfs =func(u int){
visited[u]=1for_, v :=range edges[u]{if visited[v]==0{dfs(v)if!valid {return}}elseif visited[v]==1{
valid =falsereturn}}
visited[u]=2
result =append(result, u)}for_, info :=range prerequisites {
edges[info[1]]=append(edges[info[1]], info[0])}for i :=0; i < numCourses && valid; i++{if visited[i]==0{dfs(i)}}if!valid {return[]int{}}for i :=0; i <len(result)/2; i ++{
result[i], result[numCourses-i-1]= result[numCourses-i-1], result[i]}return result
}
第二百一十一题:
classWordDictionary{public:struct Node {bool is_end;
Node *son[26];Node(){
is_end =false;for(int i =0; i <26; i ++) son[i]=NULL;}}*root;/** Initialize your data structure here. */WordDictionary(){
root =newNode();}/** Adds a word into the data structure. */voidaddWord(string word){auto p = root;for(auto c: word){int u = c -'a';if(!p->son[u]) p->son[u]=newNode();
p = p->son[u];}
p->is_end =true;}/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */boolsearch(string word){returndfs(root, word,0);}booldfs(Node* p, string& word,int i){if(i == word.size())return p->is_end;if(word[i]!='.'){int u = word[i]-'a';if(!p->son[u])returnfalse;returndfs(p->son[u], word, i +1);}else{for(int j =0; j <26; j ++)if(p->son[j]&&dfs(p->son[j], word, i +1))returntrue;returnfalse;}}};/**
* Your WordDictionary object will be instantiated and called as such:
* WordDictionary* obj = new WordDictionary();
* obj->addWord(word);
* bool param_2 = obj->search(word);
*/
classWordDictionary{classTrieNode{
TrieNode[] children;boolean flag;publicTrieNode(){
children =newTrieNode[26];
flag =false;for(int i =0; i <26; i++){
children[i]= null;}}}
TrieNode root;/** Initialize your data structure here. */publicWordDictionary(){
root =newTrieNode();}/** Adds a word into the data structure. */publicvoidaddWord(String word){char[] array = word.toCharArray();
TrieNode cur = root;for(int i =0; i < array.length; i++){// 当前孩子是否存在if(cur.children[array[i]-'a']== null){
cur.children[array[i]-'a']=newTrieNode();}
cur = cur.children[array[i]-'a'];}// 当前节点代表结束
cur.flag =true;}/**
* Returns if the word is in the data structure. A word could contain the
* dot character '.' to represent any one letter.
*/publicbooleansearch(String word){returnsearchHelp(word, root);}privatebooleansearchHelp(String word, TrieNode root){char[] array = word.toCharArray();
TrieNode cur = root;for(int i =0; i < array.length; i++){// 对于 . , 递归的判断所有不为空的孩子if(array[i]=='.'){for(int j =0;j <26; j++){if(cur.children[j]!= null){if(searchHelp(word.substring(i +1),cur.children[j])){returntrue;}}}returnfalse;}// 不含有当前节点if(cur.children[array[i]-'a']== null){returnfalse;}
cur = cur.children[array[i]-'a'];}// 当前节点是否为是某个单词的结束return cur.flag;}}
classWordDictionary:def__init__(self):
self.d = collections.defaultdict(list)defaddWord(self, word:str)->None:
self.d[len(word)]+=[word]defsearch(self, word:str)->bool:
n =len(word)
f =lambda s:all(map(lambda i: word[i]in{s[i],'.'},range(n)))#匹配函数,比写正则要快不少returnany(map(f, self.d[n]))
type WordDictionary struct{
isEnd bool
next [26]*WordDictionary
}/** Initialize your data structure here. */funcConstructor() WordDictionary {return WordDictionary{}}/** Adds a word into the data structure. */func(this *WordDictionary)AddWord(word string){for_, v :=range word {if this.next[v-'a']==nil{
this.next[v-'a']=&WordDictionary{}//新增节点}
this = this.next[v-'a']}
this.isEnd =true//标记该节点是最后一个节点}/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */func(this *WordDictionary)Search(word string)bool{var searchHelp func(word string, node *WordDictionary)bool
searchHelp =func(word string, node *WordDictionary)bool{for i :=0; i <len(word); i++{if word[i]=='.'{for_, dictionary :=range node.next {if dictionary !=nil{ifsearchHelp(word[i+1:], dictionary){//遇到'.'的时候跳过'.'继续匹配接下来的字符,树的深度进1returntrue}}}returnfalse}if node.next[word[i]-'a']==nil{returnfalse}else{
node = node.next[word[i]-'a']}}return node.isEnd ==true}returnsearchHelp(word, this)}
二百一十二题:
classSolution{public:struct Node {int id;
Node *son[26];Node(){
id =-1;for(int i =0; i <26; i ++) son[i]=NULL;}}*root;
unordered_set<int> ids;
vector<vector<char>> g;int dx[4]={-1,0,1,0}, dy[4]={0,1,0,-1};voidinsert(string& word,int id){auto p = root;for(auto c: word){int u = c -'a';if(!p->son[u]) p->son[u]=newNode();
p = p->son[u];}
p->id = id;}
vector<string>findWords(vector<vector<char>>& board, vector<string>& words){
g = board;
root =newNode();for(int i =0; i < words.size(); i ++)insert(words[i], i);for(int i =0; i < g.size(); i ++)for(int j =0; j < g[i].size(); j ++){int u = g[i][j]-'a';if(root->son[u])dfs(i, j, root->son[u]);}
vector<string> res;for(auto id: ids) res.push_back(words[id]);return res;}voiddfs(int x,int y, Node* p){if(p->id !=-1) ids.insert(p->id);char t = g[x][y];
g[x][y]='.';for(int i =0; i <4; i ++){int a = x + dx[i], b = y + dy[i];if(a >=0&& a < g.size()&& b >=0&& b < g[0].size()&& g[a][b]!='.'){int u = g[a][b]-'a';if(p->son[u])dfs(a, b, p->son[u]);}}
g[x][y]= t;}};
classTrieNode{
HashMap<Character, TrieNode> children =newHashMap<Character, TrieNode>();
String word = null;publicTrieNode(){}}classSolution{char[][] _board = null;
ArrayList<String> _result =newArrayList<String>();public List<String>findWords(char[][] board, String[] words){// Step 1). Construct the Trie
TrieNode root =newTrieNode();for(String word : words){
TrieNode node = root;for(Character letter : word.toCharArray()){if(node.children.containsKey(letter)){
node = node.children.get(letter);}else{
TrieNode newNode =newTrieNode();
node.children.put(letter, newNode);
node = newNode;}}
node.word = word;// store words in Trie}this._board = board;// Step 2). Backtracking starting for each cell in the boardfor(int row =0; row < board.length;++row){for(int col =0; col < board[row].length;++col){if(root.children.containsKey(board[row][col])){backtracking(row, col, root);}}}returnthis._result;}privatevoidbacktracking(int row,int col, TrieNode parent){
Character letter =this._board[row][col];
TrieNode currNode = parent.children.get(letter);// check if there is any matchif(currNode.word != null){this._result.add(currNode.word);
currNode.word = null;}// mark the current letter before the EXPLORATIONthis._board[row][col]='#';// explore neighbor cells in around-clock directions: up, right, down, leftint[] rowOffset ={-1,0,1,0};int[] colOffset ={0,1,0,-1};for(int i =0; i <4;++i){int newRow = row + rowOffset[i];int newCol = col + colOffset[i];if(newRow <0|| newRow >=this._board.length || newCol <0|| newCol >=this._board[0].length){continue;}if(currNode.children.containsKey(this._board[newRow][newCol])){backtracking(newRow, newCol, currNode);}}// End of EXPLORATION, restore the original letter in the board.this._board[row][col]= letter;// Optimization: incrementally remove the leaf nodesif(currNode.children.isEmpty()){
parent.children.remove(letter);}}}
classSolution:deffindWords(self, board: List[List[str]], words: List[str])-> List[str]:
WORD_KEY ='$'
trie ={}for word in words:
node = trie
for letter in word:# retrieve the next node; If not found, create a empty node.
node = node.setdefault(letter,{})# mark the existence of a word in trie node
node[WORD_KEY]= word
rowNum =len(board)
colNum =len(board[0])
matchedWords =[]defbacktracking(row, col, parent):
letter = board[row][col]
currNode = parent[letter]# check if we find a match of word
word_match = currNode.pop(WORD_KEY,False)if word_match:# also we removed the matched word to avoid duplicates,# as well as avoiding using set() for results.
matchedWords.append(word_match)# Before the EXPLORATION, mark the cell as visited
board[row][col]='#'# Explore the neighbors in 4 directions, i.e. up, right, down, leftfor(rowOffset, colOffset)in[(-1,0),(0,1),(1,0),(0,-1)]:
newRow, newCol = row + rowOffset, col + colOffset
if newRow <0or newRow >= rowNum or newCol <0or newCol >= colNum:continueifnot board[newRow][newCol]in currNode:continue
backtracking(newRow, newCol, currNode)# End of EXPLORATION, we restore the cell
board[row][col]= letter
# Optimization: incrementally remove the matched leaf node in Trie.ifnot currNode:
parent.pop(letter)for row inrange(rowNum):for col inrange(colNum):# starting from each of the cellsif board[row][col]in trie:
backtracking(row, col, trie)return matchedWords
funcfindWords(board [][]byte, words []string)[]string{var L =len(board)var W =len(board[0])var dfs func(i , j , k , t int)bool
dfs =func(i , j , k , t int)bool{if board[i][j]!= words[t][k]{returnfalse}if k ==len(words[t])-1{returntrue}
board[i][j]=' 'deferfunc(i , j int, b byte){board[i][j]= b}(i , j , words[t][k])var b boolif i +1< L && board[i +1][j]!=' '{
b =dfs(i +1, j , k +1, t)if b {return b
}}if i -1>=0&& board[i -1][j]!=' '{
b =dfs(i -1, j , k +1, t)if b {return b
}}if j +1< W && board[i][j +1]!=' '{
b =dfs(i , j +1, k +1, t )if b {return b
}}if j -1>=0&& board[i][j -1]!=' '{
b =dfs(i , j -1, k +1, t )if b {return b
}}returnfalse}var i intvar j intvar k intvar flag boolvar result []stringfor i =0; i <len(words); i ++{
flag =falsefor j =0; j < L ; j ++{for k =0; k < W; k ++{
flag =dfs(j , k ,0, i)if flag {break}}if flag {break}}if flag {
result =append(result , words[i])}}return result
}
第二百一十三题:
classSolution{public:introb(vector<int>& nums){int n = nums.size();if(!n)return0;if(n ==1)return nums[0];
vector<int>f(n +1),g(n +1);for(int i =2; i <= n; i ++){
f[i]= g[i -1]+ nums[i -1];
g[i]=max(f[i -1], g[i -1]);}int res =max(f[n], g[n]);
f[1]= nums[0];
g[1]= INT_MIN;for(int i =2; i <= n; i ++){
f[i]= g[i -1]+ nums[i -1];
g[i]=max(f[i -1], g[i -1]);}returnmax(res, g[n]);}};
classSolution:defrob(self, nums:[int])->int:defmy_rob(nums):
cur, pre =0,0for num in nums:
cur, pre =max(pre + num, cur), cur
return cur
returnmax(my_rob(nums[:-1]),my_rob(nums[1:]))iflen(nums)!=1else nums[0]
funcrob(nums []int)int{iflen(nums)==0{return0}iflen(nums)==1{return nums[0]}// 分成不含第一个和不含最后一个returnmax(robV1(nums[1:]),robV1(nums[:len(nums)-1]))}// 打家劫舍1 的代码搬过来用一下funcrobV1(nums []int)int{iflen(nums)==0{return0}// 补2个0在前面 便于统一处理
nums=append([]int{0,0},nums...)for i:=2;i<len(nums);i++{// 偷到第i间房子的时候的最大金额
nums[i]=max(nums[i-2]+nums[i],nums[i-1])}return nums[len(nums)-1]}funcmax(a,b int)int{if a>b{return a
}return b
}
第二百零七题:class Solution {public: bool canFinish(int n, vector<vector<int>>& edges) { vector<vector<int>> g(n); vector<int> d(n); for (auto& e: edges) { int b = e[0], a = e[1];