在树(图/状态集)中寻找特定结点
递归写法
visited = set()
def dfs(node, visited):
if node in visited: # terminator
# already visited
return
visited.add(node)
# process current node here.
...
for next_node in node.children():
if not next_node in visited:
dfs(next_node, visited)
非递归写法
def DFS(self, tree):
if tree.root is None:
return []
visited, stack = [], [tree.root]
while stack:
node = stack.pop()
visited.add(node)
process (node)
nodes = generate_related_nodes(node)
stack.push(nodes)
# other processing work
...
void bfs(Node* root) {
map visited;
if(!root) return ;
queue queueNode;
queueNode.push(root);
while (!queueNode.empty()) {
Node* node = queueNode.top();
queueNode.pop();
if (visited.count(node->val)) continue;
visited[node->val] = 1;
for (int i = 0; i < node->children.size(); ++i) {
queueNode.push(node->children[i]);
}
}
return ;
}
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
二叉树:[3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层序遍历结果:
[
[3],
[9,20],
[15,7]
]
思路
只要你相信自己,平心静气的慢慢写。总能写出来的
class Solution {
public:
vector> levelOrder(TreeNode* root) {
vector>res;
if(!root) return res;
queueq;
q.push(root);
vectortemp;
while(!q.empty()){
int size = q.size();
for(int i=0; ileft) q.push(current->left);
if(current != nullptr && current->right) q.push(current->right);
temp.push_back(current->val);
q.pop();
}
res.push_back(temp);
temp.clear();
}
return res;
}
};
一条基因序列由一个带有8个字符的字符串表示,其中每个字符都属于 "A", "C", "G", "T"中的任意一个。
假设我们要调查一个基因序列的变化。一次基因变化意味着这个基因序列中的一个字符发生了变化。
例如,基因序列由"AACCGGTT" 变化至 "AACCGGTA" 即发生了一次基因变化。
与此同时,每一次基因变化的结果,都需要是一个合法的基因串,即该结果属于一个基因库。
现在给定3个参数 — start, end, bank,分别代表起始基因序列,目标基因序列及基因库,请找出能够使起始基因序列变化为目标基因序列所需的最少变化次数。如果无法实现目标变化,请返回 -1。
注意:
示例 1:
start: "AACCGGTT"
end: "AACCGGTA"
bank: ["AACCGGTA"]返回值: 1
示例 2:
start: "AACCGGTT"
end: "AAACGGTA"
bank: ["AACCGGTA", "AACCGCTA", "AAACGGTA"]返回值: 2
示例 3:
start: "AAAAACCC"
end: "AACCCCCC"
bank: ["AAAACCCC", "AAACCCCC", "AACCCCCC"]返回值: 3
思路:
宽搜。依次start中的每个字母为“ATCG”,检测bank中是否存在该字符,如果存在,则记录下转变了多少个字母才转为该字符串的。
以此类推,当匹配到与end相同的字符串时,返回匹配的步数。
class Solution {
public:
int minMutation(string start, string end, vector& bank) {
unordered_setcandidate(bank.begin(), bank.end());
queue>q;
q.push({start,0});
string gene;
int step;
while(!q.empty()){
if(q.front().first == end){
return q.front().second;
}
gene=q.front().first;
step = q.front().second;
q.pop();
for (int i = 0; i < gene.length(); i++){
char cur_char = gene[i];
for(char base:"ATCG"){
if(gene[i]==base) continue; //相同则无需变换
gene[i] = base; //修改碱基
if(candidate.find(gene)!=candidate.end()){
q.push({gene,step+1});
candidate.erase(gene);
}
}
gene[i]=cur_char;
}
}
return -1;
}
};
您需要在二叉树的每一行中找到最大的值。
示例:
输入:
1
/ \
3 2
/ \ \
5 3 9输出: [1, 3, 9]
思路:
层序遍历(也可以视为宽度优先搜索)。使用变量存储该层中最大的值。
class Solution {
public:
vector largestValues(TreeNode* root) {
vectorres;
if(!root)return res;
queueq;
q.push(root);
while(!q.empty()){
int size = q.size();
int max = q.front()->val;
for(int i=0; ival>max?q.front()->val:max;
if(current!=nullptr && current->left) q.push(current->left);
if(current!=nullptr && current->right) q.push(current->right);
q.pop();
}
res.push_back(max);
}
return res;
}
};
彩蛋:http://music.163.com/song?id=1317308643&userid=287398539 这首歌超好听
字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列:
给你两个单词 beginWord 和 endWord 和一个字典 wordList ,找到从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0。
示例 1:
输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
输出:5
解释:一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的长度 5。
示例 2:
输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
输出:0
解释:endWord "cog" 不在字典中,所以无法进行转换。
提示:
思路
宽度优先搜索。
for i 0:len_word //遍历整个单词
oldchar = word[i]
for j 'a':'z' //遍历26个字母
if (oldchar == j)
continue
word[i] = j //得到新单词
if (dict.find(word) or word == end) //若该单词在dict中或等于end
queue.push(word)
dict.erase(word)
word[i] = oldchar //回溯,恢复当前单词
使用宽搜实现了一版,最后报错超时
class Solution {
public:
int ladderLength(string start, string end, vector& wordList ) {
unordered_set dict;
for(auto i:wordList ){
dict.insert(i);
}
if(dict.find(start)==dict.end()
|| dict.find(end)==dict.end())
return 0;
int n=start.size();
queue queue;
int length = 2;
if (start == end) { //若起始单词等于终点单词,直接返回1
return 1;
}
queue.push(start);
dict.erase(start); //删除dict中的起点单词(若存在的话)
while(!queue.empty()){
int size = queue.size();
for(int i=0; i
给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列。转换需遵循如下规则:
说明:
示例 1:
输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]输出:
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
示例 2:
输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]输出: []
解释: endWord "cog" 不在字典中,所以不存在符合要求的转换序列。
难题先跳过了
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
输出:1
示例 2:
输入:grid = [
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
输出:3
提示:
思路:
遍历二维数组,遇到岛就将其夷为平地。
未完待续 2021 03 23 最近有点堕落了,罪过罪过