leetcode演算法之遍歷(BFS與DFS)
今天來盤一盤 **遍歷 ** 這類題目
使用python刷題分類整理的筆記,請參考: //github.com/lxztju/leetcode-algorithm/tree/v1
遍歷
層次遍歷(BFS)
- 102 二叉樹的層序遍歷(medium)
- 637 二叉樹的層平均值 (Easy)
- 513 找樹左下角的值 (medium)
深度優先遍歷(DFS)
- 144 二叉樹的前序遍歷 (meidum)
- 145 二叉樹的後序遍歷 (hard)
- 94 二叉樹的中序遍歷 (Medium)
BFS
寬度優先遍歷(BFS)採用隊列的方式,依次遍歷一棵樹。
基本的套路程式碼,就是102題目中的程式碼思路。
102 二叉樹的層序遍歷(medium)
- 題解
BFS- 使用隊列存儲當前節點的指針以及當前節點的層次
- 循環遍歷隊列中的元素
- 對於一個隊首節點,如果其左子節點存在就將左子節點入隊,如果右子節點存在,將右子節點入隊列
- 按照隊首節點的層次數,將節點的值插入vector中對於的位置。
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
if (root == nullptr) return {};
// 使用隊列存儲節點與節點所對應的層次
queue<pair<TreeNode*, int>> nodeQ;
vector<vector<int>> res;
// 將根節點以及對應的層次0,入隊
nodeQ.push(make_pair(root, 0));
// 如果隊列不為空,就一直遍歷隊列元素
while (!nodeQ.empty()){
// 拿出隊首的節點指針以及層次
auto nodeLevel = nodeQ.front();
auto nodePoint = nodeLevel.first;
int level = nodeLevel.second;
nodeQ.pop(); // 隊首元素出隊
if (res.size() <= level){
res.push_back({});
}
res[level].push_back(nodePoint->val);
// 如果左子樹存在,就將左子節點入隊
if (nodePoint->left){
nodeQ.push(make_pair(nodePoint->left, level+1));
}
// 如果右子樹存在,就將右子節點入隊
if (nodePoint->right){
nodeQ.push(make_pair(nodePoint->right, level+1));
}
}
return res;
}
};
637 二叉樹的層平均值 (Easy)
與上一題一致
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {
if (! root) return {};
vector<double> nodesum;
vector<int> cnt;
queue<pair<TreeNode*, int>> nodeQ;
nodeQ.push(make_pair(root, 0));
while (!nodeQ.empty()){
// 拿出隊首的節點指針以及層次
auto nodeLevel = nodeQ.front();
auto nodePoint = nodeLevel.first;
int level = nodeLevel.second;
nodeQ.pop(); // 隊首元素出隊
if (nodesum.size() <= level){
nodesum.push_back(nodePoint->val);
cnt.push_back(1);
}
else{
nodesum[level] += nodePoint->val;
cnt[level]++;
}
// 如果左子樹存在,就將左子節點入隊
if (nodePoint->left){
nodeQ.push(make_pair(nodePoint->left, level+1));
}
// 如果右子樹存在,就將右子節點入隊
if (nodePoint->right){
nodeQ.push(make_pair(nodePoint->right, level+1));
}
}
for (int i = 0; i< nodesum.size(); i++){
nodesum[i] /= cnt[i];
}
return nodesum;
}
};
513 找樹左下角的值 (medium)
- 題解: 最左邊的值,就是採用層次遍歷保存每層開始的第一個值
- 同樣的層次遍歷方法。
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
if (root == nullptr) return {};
// 使用隊列存儲節點與節點所對應的層次
queue<pair<TreeNode*, int>> nodeQ;
// pair的第一個參數為每層的第一個節點值,第二個參數為層次
pair<int, int> res(0, -1);
// 將根節點以及對應的層次0,入隊
nodeQ.push(make_pair(root, 0));
// 如果隊列不為空,就一直遍歷隊列元素
while (!nodeQ.empty()){
// 拿出隊首的節點指針以及層次
auto nodeLevel = nodeQ.front();
auto nodePoint = nodeLevel.first;
int level = nodeLevel.second;
nodeQ.pop(); // 隊首元素出隊
// 如果開始了一個新的層次,將在這一層最左側的元素保存。
if (level > res.second){
res.first = nodePoint->val;
res.second = level;
}
// 如果左子樹存在,就將左子節點入隊
if (nodePoint->left){
nodeQ.push(make_pair(nodePoint->left, level+1));
}
// 如果右子樹存在,就將右子節點入隊
if (nodePoint->right){
nodeQ.push(make_pair(nodePoint->right, level+1));
}
}
return res.first;
}
};
DFS
深度優先遍歷(DFS)就是遞歸訪問一棵樹。
144 二叉樹的前序遍歷 (meidum)
前序遍歷: 根——左——右
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
preorder(root, res);
return res;
}
void preorder(TreeNode* root, vector<int>& res){
if (root == nullptr) return;
res.push_back(root->val);
preorder(root->left, res);
preorder(root->right, res);
}
};
145 二叉樹的後序遍歷 (hard)
後序遍歷: 左——右——根
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
postorder(root, res);
return res;
}
void postorder(TreeNode* root, vector<int>& res){
if (root == nullptr) return;
postorder(root->left, res);
postorder(root->right, res);
res.push_back(root->val);
}
};
94 二叉樹的中序遍歷 (Medium)
中序遍歷: 左——根——右
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
inorder(root, res);
return res;
}
void inorder(TreeNode* root, vector<int> & res){
if (root == nullptr) return ;
inorder(root->left, res);
res.push_back(root->val);
inorder(root->right, res);
}
};
更多分類刷題資料
-
微信公眾號: 小哲AI

-
GitHub地址: //github.com/lxztju/leetcode-algorithm
-
csdn部落格: //blog.csdn.net/lxztju
-
知乎專欄: 小哲AI
-
AI研習社專欄:小哲AI

