普通版 剑指 Offer 浅刷浅刷( 九 )


每次都对队列使用栈进行反转,反转之后节点的存入顺序都要发生改变,如果从左到右进行遍历就得先存左孩子再存右孩子,如果从右到左进行遍历就得先存右孩子再存左孩子 。
剑指 Offer 33. 二叉搜索树的后序遍历序列
//方法一:class Solution {public:bool verifyPostorder(vector& postorder) {stack myStack; //单调栈使用,单调递增的单调栈int nearRoot = INT_MAX; //存储最近节点的root节点//逆向遍历,就是翻转的先序遍历for (int i = postorder.size() - 1; i >= 0; i--) {if (postorder[i] > nearRoot) {return 0;}//单调栈非空,并且数组的该元素小于栈顶元素,即不满足单调栈的特性,就记录弹出栈顶的值(这个值就是其最近的根节点的值),然后弹出栈顶元素while (!myStack.empty() && postorder[i] < myStack.top()) {nearRoot = myStack.top();myStack.pop();}//这个新元素入栈myStack.push(postorder[i]);}return 1;}};//方法二:class Solution {public:bool verifyPostorder(vector& postorder) {return judgeVector(postorder, 0, postorder.size() - 1);}private:bool judgeVector(vector &postorder, int i, int j) {//数组长度是1,那么肯定就是了if (i >= j) {return 1;}//找第一个大于root的位置,其左边肯定小于root,右边肯定大于root,根据这个道理对其进行判断int m = i;while (m < j && postorder[m] < postorder[j]) {m++;}//判断其右边是否大于rootint p = m;while (p < j && postorder[p] > postorder[j]) {p++;}//如果右边都大于root那么p到最后一定等于jreturn p == j && judgeVector(postorder, i, m - 1) && judgeVector(postorder, m, j - 1);}};
方法一:单调栈的使用,题目说要判断一个数组是不是后续遍历(left->righe->root)的结果,那我们不妨将其数组颠倒过来,那是不是就是(root->right->left)这不就成了从right开始的先序遍历,那我们只要掌握了先序遍历的规则,岂不是迎刃而解,这里使用到了单调栈,因为我们是从right开始的,根据二叉搜索树的概念,那么right>root,根据这个特性,我们使用单调递增的栈,如果栈非空并且访问的该元素大于栈顶元素那么就表示还是访问right,我们直接压入就行,不需要其他操作,但是若一个元素小于栈顶元素,那么就表示某一个root的right访问完了,现在该访问这个root的left了,那么现在的问题就转变成了怎么记录下这个root的值,以便做题,那我们能想到,二叉搜索树right都是大于root值的,并且我们刚才已经将right的值都已经存入单调栈了,那么我们只需要一只弹出刚才栈顶的元素,并记录下来,知道栈顶元素小于该值就说明上一个弹出的栈顶元素就是现在数组所指向位置索引的root了,这样问题就解决了,那么到底怎么他才不是一个二叉搜索的后序遍历呢,其实很简单,二叉搜索树的root>left,right>root我们刚才又知道了root的值,那么我们直接比较就行了,如果数组访问的元素大于之前记录的root值即left>root了,那么就不是了 。
方法二:
剑指 Offer 34. 二叉树中和为某一值的路径
/*** Definition for a binary tree node.* struct TreeNode {*int val;*TreeNode *left;*TreeNode *right;*TreeNode() : val(0), left(nullptr), right(nullptr) {}*TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/class Solution {public:vector> pathSum(TreeNode* root, int target) {vector tempVector;vector> myVector;dfs(root, target, myVector, tempVector);return myVector;}void dfs(TreeNode *root, int target, vector>& myVector, vector& tempVector) {if (!root) {return;}target -= root->val;tempVector.push_back(root->val);if (!target && !root->left && !root->right) {myVector.push_back(tempVector);} else {dfs(root->left, target, myVector, tempVector);dfs(root->right, target, myVector, tempVector);}tempVector.pop_back();//target += root->val;这个可以不要,因为我们是值传递,而不是引用传递,所以不会修改掉原值}};