中国建设银行个人卡信息网站,深圳专业手机网站建设,千万不要去代理记账公司上班,制作软件的手机软件513.找树左下角的值
思路一#xff1a;层序遍历#xff0c;每一层判断是不是最后一层#xff0c;是的话直接返回第一个; 如何判断是不是最后一层呢#xff0c;首先队列头部#xff0c;其次记录左右子节点都没有的节点数是不是等于que.size()#xff1b;或…513.找树左下角的值
思路一层序遍历每一层判断是不是最后一层是的话直接返回第一个; 如何判断是不是最后一层呢首先队列头部其次记录左右子节点都没有的节点数是不是等于que.size()或者直接判断队列是否为空。其实也不用判断因为最后一次记录的队列头就是最左下角节点
class Solution {
public:int findBottomLeftValue(TreeNode* root) {queueTreeNode*que;que.push(root);int res0;while(!que.empty()){int nque.size();int midque.front()-val;for(int i0;in;i){TreeNode*nodeque.front();que.pop();if(node-left)que.push(node-left);if(node-right)que.push(node-right);}if(que.empty())resmid;}return res;}
}; 思路二递归每次遍历到叶子节点时记录节点值和深度使用数组找到深度最深的第一个
class Solution {
public:vectorvectorint ans;void judge(TreeNode*root,int deepth){if(rootnullptr)return;if(root-leftnullptr root-rightnullptr)ans.push_back({deepth,root-val});judge(root-left,deepth1);judge(root-right,deepth1);}int findBottomLeftValue(TreeNode* root) {judge(root,0);int mid0,res0;for(int i0;ians.size();i){if(ans[i][0]mid){midans[i][0];resi;}}return ans[res][1];}
};
思路三递归不使用额外空间每次遍历到叶子节点是进行深度判断
class Solution {
public:int maxDeepth-1;int res0;void judge(TreeNode*root,int deepth){if(rootnullptr)return;if(root-leftnullptr root-rightnullptr)//遍历到叶子节点时{if(deepthmaxDeepth){maxDeepthdeepth;resroot-val;}}judge(root-left,deepth1);judge(root-right,deepth1);}int findBottomLeftValue(TreeNode* root) {judge(root,0);return res;}
};
注意deepth是值传递只有父节点的改变影响子节点的值同为子节点是相互不影响的所以相当于回溯了。
112.路径总和
思路递归前序遍历二叉树在叶子节点处进行判断
class Solution {
public:bool resfalse;void judge(TreeNode*root,int targetSum,int sum){if(rootnullptr)return;if(root-leftnullptr root-rightnullptr){if(sumroot-valtargetSum)restrue;//coutsum;}sumroot-val;// if(sumtargetSum)// return;judge(root-left,targetSum,sum);judge(root-right,targetSum,sum);}bool hasPathSum(TreeNode* root, int targetSum) {judge(root,targetSum,0);return res;}
};
113.路径总和||
思路一还是直接递归然后在叶子节点处判断
注意每次当前节点判断完之后需要删除路径的最后一个节点即回溯到另一个节点
class Solution {
public:vectorvectorintres;vectorintmids;void judge(TreeNode*root,int targetSum,int sum){if(rootnullptr)return;if(root-leftnullptr root-rightnullptr){if(sumroot-valtargetSum){mids.push_back(root-val);res.push_back(mids);mids.erase(mids.end()-1);return;}}sumroot-val;mids.push_back(root-val);judge(root-left,targetSum,sum);judge(root-right,targetSum,sum);mids.erase(mids.end()-1);}vectorvectorint pathSum(TreeNode* root, int targetSum) {//思路一直接递归在叶子节点处判断if(rootnullptr)return vectorvectorint();judge(root,targetSum,0);return res;}
};
106.从中序与后序遍历序列构造二叉树
分析这个递归切割的想法很精妙 class Solution {
private:TreeNode*judge(vectorintinorder,vectorintpostorder){if(postorder.size()0) return NULL;//后续遍历数组最后一个元素就是当前二叉树的中间节点int rootValuepostorder[postorder.size()-1];TreeNode*rootnew TreeNode(rootValue);//叶子节点if(postorder.size()1) return root;//找到中序遍历的切割点int midLastIndex;for(midLastIndex0;midLastIndexinorder.size();midLastIndex){if(inorder[midLastIndex]rootValue) break;}//切割中序数组//左闭右开区间[0,midLastIndex]vectorint leftInorder(inorder.begin(),inorder.begin()midLastIndex);vectorint rightInorder(inorder.begin()midLastIndex1,inorder.end());//删除后序数组的末尾元素postorder.resize(postorder.size()-1);//切割后序数组//依然左闭右开注意这里使用了左中序数组大小作为切割点vectorint leftPostorder(postorder.begin(),postorder.begin()leftInorder.size());vectorint rightPostorder(postorder.begin()leftInorder.size(),postorder.end());root-leftjudge(leftInorder,leftPostorder);root-rightjudge(rightInorder,rightPostorder);return root;}
public:TreeNode* buildTree(vectorint inorder, vectorint postorder) {if(inorder.empty() || postorder.empty()) return nullptr;return judge(inorder,postorder);}
};
105.从前序和中序遍历序列构造二叉树
分析和中序和后序遍历序列构造二叉树几乎一摸一样
思路每次构建中间节点把前序和中序遍历序列进行分割再递归到下一层把分割后的序列传入下一层最后依次把创建出来的中间节点返回给上一层连接回溯
class Solution {
public:TreeNode* judge(vectorintpreorder,vectorintinorder){if(preorder.size()0) return nullptr;int rootValuepreorder[0];TreeNode*rootnew TreeNode(rootValue);if(preorder.size()1) return root;//在中序序列中找到切割点int mid;for(mid0;midinorder.size();mid){if(inorder[mid]rootValue) break;}//对中序遍历序列进行切割vectorintleftInorder(inorder.begin(),inorder.begin()mid);vectorintrightInorder(inorder.begin()mid1,inorder.end());//删除中间节点preorder.erase(preorder.begin());//对前序遍历序列进行切割 注意中间节点已经删除所以第一个元素也为左边前序vectorintleftPreorder(preorder.begin(),preorder.begin()leftInorder.size());vectorintrightPreorder(preorder.begin()leftInorder.size(),preorder.end());//把切割后的序列传入下一层root-leftjudge(leftPreorder,leftInorder);root-rightjudge(rightPreorder,rightInorder);//把创建出来的中间节点传入上一层return root;}TreeNode* buildTree(vectorint preorder, vectorint inorder) {if(preorder.empty() || inorder.empty()) return nullptr;return judge(preorder,inorder);}
};
107.二叉树的层序遍历II
思路简单的层序遍历加入栈然后取出
class Solution {
public:vectorvectorint levelOrderBottom(TreeNode* root) {//思路层序遍历然后把每一层的数据加入栈中最后再从栈中取出vectorvectorintres;if(rootnullptr) return res;queueTreeNode*que;stackvectorintmidSt;que.push(root);while(!que.empty()){int nque.size();vectorintmids;for(int i0;in;i){TreeNode*curque.front();mids.push_back(cur-val);que.pop();if(cur-left) que.push(cur-left);if(cur-right) que.push(cur-right);}midSt.push(mids);}coutmidSt.size();int lenmidSt.size();for(int i0;ilen;i){res.push_back(midSt.top());midSt.pop();}return res;}
};
今日问题43.字符串相乘
849. 到最近的人的最大距离