牛客剑指offer刷题记录(四)

来源:互联网 发布:新致软件成都分公司 编辑:程序博客网 时间:2024/06/03 14:53

包含min函数的栈

最小栈问题,这里需要在class中维护两个栈,一个栈用于正常的push、pop、top操作,另一个栈就是维护当前最小值的栈。

具体做法是,假设现在s2是最小栈,栈顶元素时当前最小值,此时push一个新的值value过来,我们判断,如果value比最小栈的栈顶元素小,那么,需要将value作为新的最小值push到栈中,否则的话则把当前最小值作为本次插入之后的最小值再push一次,即:s2.push(s2.top())

#include <iostream>#include <stack>using namespace std;class Solution {public:    void push(int value) {        s1.push(value);        if (s2.empty()||value < s2.top())        {            s2.push(value);        }        else        {            s2.push(s2.top());        }    }    void pop() {        s1.pop();        s2.pop();    }    int top() {        return s1.top();    }    int min() {        return s2.top();    }private:    stack<int>s1;//正常的栈    stack<int>s2;//最小栈};

栈的压入、弹出序列

判断压入序列是否能够得到弹出序列…

核心思路是需要一个辅助栈,如果弹出序列的当前数字刚好是栈顶元素,那么直接弹出,否则的话继续压入,直到把需要弹出的数字压入到栈中为止。

这是一个循环操作,也即需要把满足条件(栈顶元素等于弹出序列的当前元素)的所有值依次弹出。

如果把所有的数字都压入完毕,最终弹出的个数却比较少,导致栈中仍然存在元素,说明了不能完成弹出序列。

class Solution {private:    stack<int>s;public:    bool IsPopOrder(vector<int> pushV, vector<int> popV)    {        int j = 0;        for (int i = 0; i < pushV.size(); ++i)        {            s.push(pushV[i]);            while (!s.empty() && s.top() == popV[j])            {                s.pop();                ++j;            }        }        if (s.empty())            return true;        else            return false;    }};

从上往下打印二叉树

二叉树层序遍历,BFS的思想,先入队根节点,如果左子树不为空,入队左子树,如果右子树不为空则入队右子树。直到队空为止:

/*struct TreeNode {    int val;    struct TreeNode *left;    struct TreeNode *right;    TreeNode(int x) :            val(x), left(NULL), right(NULL) {    }};*/class Solution {public:    vector<int> PrintFromTopToBottom(TreeNode* root) {        if (nullptr == root)            return vector<int>();        queue<TreeNode*>q;        q.push(root);        vector<int>result;        while (!q.empty())        {            TreeNode* r = q.front();            q.pop();            result.push_back(r->val);            if (r->left != nullptr)                q.push(r->left);            if (r->right != nullptr)                q.push(r->right);        }        return result;    }};

二叉搜索树的后序遍历序列

二叉搜索树,左子树比根节点小,右子树比根节点大。对于后序遍历来说,根节点位于序列的最后,剩下的部分,分为两个部分,一部分比根小的是左子树,一部分比根大的是是右子树。

具体步骤:
1.先找到根(假设索引是r)
2.把右子树序列找出来(从r-1往前搜索直到找到不满足大于根节点的节点)
3.把左子树序列找出来,在迭代中,只要有左子树序列中的元素大于根,则返回false。
4.递归的对左右子树进行1-3步骤。

#include <vector>#include <iostream>using namespace std;class Solution {private:    bool judge(vector<int>&a, int l, int r)    {        if (l >= r)            return true;        int j = r;//1.先找到根        int i,k;        for (i = r - 1; i >= l; --i)//把右子树找出来        {            if (a[i] < a[r])                break;        }        for (k = i; k >= l; --k)//把左子树找出来        {            if (a[k] > a[r])//只要有左子树序列大于根,立即返回false                return false;        }        //如果都满足,则需要递归找左右子树        return judge(a,l,i) && judge(a,i+1,r-1);    }public:    bool VerifySquenceOfBST(vector<int> sequence) {        if (sequence.size() == 0)            return false;        return judge(sequence, 0, sequence.size() - 1);    }};

二叉树种和为某一值的路径

根到叶子节点路径和是否为某一个target,把所有的路径找出来。
这里需要三个参数:
1.result 保存所有路径
2.path 保存当前路径
3.sum 保存当前和

具体算法思路:
1.计算当前sum值,如果当前sum值为target的值,且当前节点为叶子节点,则将当前路径添加到结果中。
2.递归左子树
3.递归右子树
4.递归返回条件root为空指针

class Solution {private:    void dfs(vector<vector<int>>&r, vector<int>path, TreeNode * root, int sum,int target)    {        if (root == nullptr)            return;        path.push_back(root->val);        sum += root->val;        if ((root->left == nullptr&&root->right == nullptr) && (sum == target))            r.push_back(path);        dfs(r, path, root->left, sum, target);        dfs(r, path, root->right, sum, target);    }public:    vector<vector<int> > FindPath(TreeNode* root, int expectNumber) {        if (nullptr == root)            return vector<vector<int>>();        vector<vector<int>>res;        vector<int>tmp;        dfs(res, tmp, root, 0,expectNumber);        return res;    }};
原创粉丝点击