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


包含min函数的栈

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

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

#include 
#include 
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>();
        queueq;
        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 
#include 
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;
    }
};

你可能感兴趣的:(笔试面试,剑指offer)