【剑指Offer】搜索与回溯算法

刷题 专栏收录该内容
36 篇文章 0 订阅

今天的题目是搜索算法(广度优先搜索),用到了树这种数据结构,题目不是特别难,但都挺有意思的。

剑指 Offer 32 - I. 从上到下打印二叉树

从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。

例如:
给定二叉树: [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回:

[3,9,20,15,7]

提示:

  1. 节点总数 <= 1000
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> levelOrder(TreeNode* root) {
        queue<TreeNode*> q;
        vector<int> ans;
        if(root == nullptr)return ans;
        q.push(root);
        while(q.empty() == false){
            TreeNode *node = q.front();
            q.pop();
            ans.push_back(node->val);
            if(node->left != nullptr)q.push(node->left);
            if(node->right != nullptr)q.push(node->right);
        }
        return ans;
    }
};

算法思路:

在学树的时候这种遍历叫层次遍历,学图的时候这叫广度优先搜索,广度优先的基本思路就是用一个队列存储每一个结点,然后执行先进先出的操作,每个弹出的结点再扩展其子节点到队列尾,这样就可以形成层次遍历(广度优先搜索)。

题目一结果

剑指 Offer 32 - II. 从上到下打印二叉树 II

从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。

例如:
给定二叉树: [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回其层次遍历结果:

[
  [3],
  [9,20],
  [15,7]
]

提示:

  1. 节点总数 <= 1000
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> ans;
        queue<TreeNode*> q;
        if(root == nullptr)return ans;
        q.push(root);
        int i = 0;
        while(q.empty() == false){
            ans.push_back({});
            for(int j = q.size(); j > 0; -- j){
                TreeNode *node = q.front();
                q.pop();
                ans[i].push_back(node->val);
                if(node->left != nullptr)q.push(node->left);
                if(node->right != nullptr)q.push(node->right);
            }
            i ++;
        }
        return ans;
    }
};

算法思路:

第二题思路和第一题思路大致相同,第二题只是在搜索时候记录该结点所在层数而已,这时只需要在弹出时做一点小改变,一批一批的弹出而不是一个个弹出,这里有个细节就是for(int j = q.size(); j > 0; -- j),这里不可以用for(int j = 0; j < q.size(); -- j),这是因为在批弹出的过程中也有新结点插入,q.size()会改变,而我的目的本来只是弹出最原始的q.size()个元素,所以后者不能用。

题目二结果

剑指 Offer 32 - III. 从上到下打印二叉树 III

请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。

例如:
给定二叉树: [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回其层次遍历结果:

[
  [3],
  [20,9],
  [15,7]
]

提示:

  1. 节点总数 <= 1000
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> ans;
        queue<TreeNode*> q;
        if(root == nullptr)return ans;
        q.push(root);
        int i = 0;
        bool tag = false;
        while(q.empty() == false){
            ans.push_back({});
            stack<int> stac;
            for(int j = q.size(); j > 0; -- j){
                TreeNode *node = q.front();
                q.pop();
                if(tag){
                    stac.push(node->val);
                }else{
                    ans[i].push_back(node->val);                   
                }
                if(node->left != nullptr)q.push(node->left);
                if(node->right != nullptr)q.push(node->right);
            }
            while(stac.empty() == false){
                ans[i].push_back(stac.top());
                stac.pop();         
            }
            tag = !tag;
            i ++;
        }
        return ans;
    }
};

算法思路:

第三题和第二题也大同小异,只是再偶数层插入结果时进行反转,这就达成了之字打印,至于如何反转可以用栈或者直接用vectorreverse,都可以实现。

题目三结果

【剑指Offer】系列:
【剑指Offer】栈
【剑指Offer】链表
【剑指Offer】字符串
【剑指Offer】查找算法
【剑指Offer】查找算法(1)

  • 1
    点赞
  • 0
    评论
  • 1
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页

打赏作者

Ryu眼神不太好

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值