算法&数据结构学习(2) 剑指offer刷题笔记(5)

面试题28. 对称的二叉树

在这里插入图片描述
解法1:递归法
思路:二叉树相关的很多问题都可以想到用递归去求解,定义一个辅助函数isMirror()帮助递归判断两棵树书否镜像。
代码如下:

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        //递归法
        if(!root) return true;
        return isMirror(root->left,root->right);
    }
    bool isMirror(TreeNode* lc, TreeNode* rc)
    {
        if(!lc && !rc) return true;
        if(!lc || !rc) return false;
        return lc->val==rc->val && isMirror(lc->left,rc->right) && isMirror(lc->right,rc->left);
    }
};

解法2:迭代

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        //迭代法
        if(!root) return true;
        queue<TreeNode*> q;
        q.push(root);
        q.push(root);
        while(!q.empty())
        {
            auto lc = q.front();q.pop();
            auto rc = q.front();q.pop();
            if(!lc && !rc) continue;//都为空继续
            if(!lc || !rc) return false;//只有一个为空直接返回
            if(lc->val!=rc->val) return false;//对称节点值不相等直接返回
            //入队顺序要对应
            q.push(lc->left);
            q.push(rc->right);
            q.push(lc->right);
            q.push(rc->left);
        }
        return true;
    }
};

面试题29. 顺时针打印矩阵在这里插入图片描述

解题思路:模拟顺时针前进路线,设置上下左右四个边界,每当遇到边界就换个方向遍历即可。
代码如下:

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if(matrix.empty()) return {};
        vector<int> res;
        int u = 0, d = matrix.size()-1;
        int l = 0, r = matrix[0].size()-1;
        while(true)
        {
            for(int i=l; i<=r; ++i)//从左往右
                res.push_back(matrix[u][i]);
            if(++u>d) break;
            for(int i=u; i<=d; ++i)//从上往下
                res.push_back(matrix[i][r]);
            if(--r<l) break;
            for(int i=r; i>=l; --i)//从右往左
                res.push_back(matrix[d][i]);
            if(--d<u) break;
            for(int i=d; i>=u; --i)//从下往上
                res.push_back(matrix[i][l]);
            if(++l>r) break;
        }
        return res;
    }
};

面试题30. 包含min函数的栈

在这里插入图片描述
思路:使用一个辅助栈s2,每当在push时判断s2是否为空或新元素是否不大于栈顶元素,如果是则需要同时入辅助栈,当pop时判断辅助栈顶元素与数据栈顶元素是否相等,如果是,则辅助栈的元素也要出栈,保持辅助栈顶元素一定是最小值。

class MinStack {
public:
    /** initialize your data structure here. */
    MinStack() {

    }
    
    void push(int x) {
        s1.push(x);
        if(s2.empty() || s2.top()>=x)//如果辅助栈空或者遇到更小的数,则入栈
            s2.push(x);
    }
    
    void pop() {
        if(s1.top()==s2.top())
            s2.pop();
        s1.pop();
    }
    
    int top() {
        return s1.top();
    }
    
    int min() {
        return s2.top();
    }
private:
    stack<int> s1;//数据栈
    stack<int> s2;//辅助栈
};

面试题31. 栈的压入、弹出序列

在这里插入图片描述
思路:对pushed序列进行模拟入栈出栈,按顺序将pushed序列的元素入栈,每次入栈就判断与poped序列的当前元素是否相等,如果相等则循环弹出。如果pushed和poped序列是对应的压入和弹出顺序,最后辅助栈内应为空,否则栈不为空。

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        //模拟栈法
        stack<int> s;
        int k=0;
        for(auto num:pushed)
        {
            s.push(num);
            while(!s.empty() && s.top()==popped[k])
            {
                s.pop();
                ++k;
            }
        }
        return s.empty();
    }
};

面试题32 - I. 从上到下打印二叉树在这里插入图片描述

思路:二叉树的层次遍历,直接使用广度优先搜索(BFS)即可。

class Solution {
public:
    vector<int> levelOrder(TreeNode* root) {
        //层次遍历(BFS)
        if(!root) return {};
        queue<TreeNode*> q;
        vector<int> res;
        q.push(root);
        while(!q.empty())
        {
            auto tmp = q.front();
            q.pop();
            res.push_back(tmp->val);
            if(tmp->left) q.push(tmp->left);
            if(tmp->right) q.push(tmp->right);
        }
        return res;
    }
};

面试题32 - II. 从上到下打印二叉树 II

在这里插入图片描述
思路:与上个题一样,都是二叉树的层次遍历,只是输出方式不同。

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        if(!root) return {};
        queue<TreeNode*> q;
        q.push(root);
        vector<vector<int>> res;
        while(!q.empty())
        {
            int k = q.size();
            vector<int> tmp;
            while(k--)
            {
                auto node = q.front();
                q.pop();
                tmp.push_back(node->val);
                if(node->left) q.push(node->left);
                if(node->right) q.push(node->right);
            }
            res.push_back(tmp);
        }
        return res;
    }
};

面试题32 - III. 从上到下打印二叉树 III

在这里插入图片描述
思路:与上一题差别很小,还是层次遍历,只是需要修改两处地方:增加一个层次标记layer,在每一层遍历完毕时,判断是否是奇数层(根节点为第0层),如果是则将结果反转再打印;

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        if(!root) return {};
        queue<TreeNode*> q;
        q.push(root);
        vector<vector<int>> res;
        int layer = 0;//添加一个层次标记
        while(!q.empty())
        {
            int k = q.size();
            vector<int> tmp;
            while(k--)
            {
                auto node = q.front();
                q.pop();
                tmp.push_back(node->val);
                if(node->left) q.push(node->left);
                if(node->right) q.push(node->right);
            }
            if(layer&1) reverse(tmp.begin(),tmp.end());//如果是奇数层(层次从0开始即根节点为第0层)则反转
            res.push_back(tmp);
            ++layer;
        }
        return res;
    }
};

今日刷题笔记题目较少,比较简单,收拾行李明天开学咯!!!继续努力!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值