问题0: 二叉树的非递归遍历方法
问题1: 判断一颗二叉树是否为二叉查找树.
问题2: 判断两个二叉树是否相同
问题3: 判断一棵树是否为平衡树
问题4: 寻找二叉树的最大和最短简单路径长度
问题5: 二叉树上简单路径的长度问题
解答0:
[0.1]前序.使用栈,访问节点后先压入右儿子,再压入左儿子即可.
1 vector<int> preorderTraversal(TreeNode *root){ 2 stack<TreeNode*> st; 3 st.push(root); 4 vector<int> res; 5 6 TreeNode *curr; 7 while(!st.empty()){ 8 curr = st.top(); 9 st.pop(); 10 11 if(curr){ 12 res.push_back(curr->val); 13 st.push(curr->right); 14 st.push(curr->left); 15 } 16 } 17 18 return res; 19 }
[0.2]中序遍历.使用一个栈,将访问过的节点压入栈中.
1 vector<int> inorderTraversal(TreeNode *root){ 2 stack<TreeNode*> st; 3 vector<int> res; 4 5 TreeNode *curr=root,*top; 6 while(!st.empty() || curr){ 7 if(curr){ 8 st.push(curr); 9 curr = curr->left; 10 }else{ 11 curr = st.top(); 12 st.pop(); 13 res.push_back(curr->val); 14 curr = curr->right; 15 } 16 } 17 18 return res; 19 }
[0.3]
方法1.后序遍历.访问左儿子前记录本节点,当再次取出节点时,存在其右儿子有没有被访问过的问题.通过记录前驱节点来辅助判断(前驱节点只在特定地点才更新).
1 vector<int> postorderTraversal(TreeNode *root) { 2 stack<TreeNode*> st; 3 vector<int> res; 4 5 TreeNode *curr=root,*prev=root,*top; 6 while(!st.empty() || curr){ 7 if(curr){ 8 st.push(curr); 9 curr = curr->left; 10 }else{ 11 curr = st.top(); 12 13 if(prev==curr->right || curr->right==NULL){ 14 st.pop(); 15 16 res.push_back(curr->val); 17 prev = curr; 18 curr = NULL; 19 }else{ 20 curr = curr->right; 21 } 22 } 23 } 24 return res; 25 }
方法2:使用两个栈,一个记录TreeNode*,另一个记录这个节点所对应的剩余访问次数.
当剩余访问次数为2时,将剩余次数减少为1,并访问其左儿子;
当剩余访问次数为1时,将剩余次数减少为0,并访问其右儿子;
当剩余访问次数为0时,访问本节点.
[0.4]层次遍历. 使用队列.
解答1:
[1.1]首先中序遍历记录节点,然后判断整个记录是否递增.
1 void inorder(TreeNode *root, vector<int>& v){ 2 if(root){ 3 inorder(root->left,v); 4 v.push_back(root->val); 5 inorder(root->right,v); 6 } 7 } 8 9 bool isAscend(vector<int>& v){ 10 int len = v.size(); 11 int i=0; 12 while(i<len-1){ 13 if(v[i] >= v[i+1]) 14 return false; 15 i++; 16 } 17 return true; 18 } 19 20 bool isValidBST(TreeNode *root) { 21 vector<int> v; 22 inorder(root,v); 23 24 return isAscend(v); 25 }
[1.2].通过观察可以发现, 方法[1.1]的比较过程就是将每个节点与其前驱节点的值作比较.那么这个比较操作能放在深搜的过程中完成吗?
1 bool isValidBST(TreeNode *root) { 2 TreeNode *curr = root,*prev = NULL; 3 stack<TreeNode*> st; 4 5 while(!st.empty() || curr){ 6 if(curr){ 7 st.push(curr); 8 curr = curr->left; 9 }else{ 10 curr = st.top(); 11 st.pop(); 12 if(prev){ 13 if(prev->val >= curr->val) 14 return false; 15 } 16 prev = curr; 17 curr = curr->right; 18 } 19 } 20 21 return true; 22 }
[1.3]使用子树中节点的左右边界来辅助进行判断.
1 bool err; 2 3 pair<int, int> dfs(TreeNode *t){ 4 pair<int, int> l, r; 5 int lbound = t->val, rbound = t->val; // 节点t的子树中节点的左右权值边界 6 if (t->left){ 7 l = dfs(t->left); 8 if (l.second >= t->val) err = true; 9 lbound = l.first;//左边界为左子树的左边界 10 } 11 if (t->right){ 12 r = dfs(t->right); 13 if (r.first <= t->val) err = true; 14 rbound = r.second;//右边界为右子树的右边界 15 } 16 return make_pair(lbound, rbound); 17 } 18 19 bool isValidBST(TreeNode *root) { 20 if (root == NULL) return true; 21 err = false; 22 dfs(root); 23 return !err; 24 }
解答2:
[2.1]可通过同步的遍历来解决.
1 bool isSameTree(TreeNode *p,TreeNode *q){ 2 if(p==NULL && q==NULL) 3 return true; 4 return (p && q && p->val==q->val && isSameTree(p->left,q->left) && isSameTree(p->right,q->right)); 5 }
解答3:
[3.1]递归方法
1 int check(TreeNode *root,bool& flag){ 2 int l = 0,r = 0; 3 if(flag && root && root->left) 4 l = check(root->left,flag) + 1; 5 if(flag && root && root->right) 6 r = check(root->right,flag) + 1; 7 if(flag) 8 flag = (abs(l-r)<=1); 9 return l>r?l:r; 10 } 11 12 bool isBalanced(TreeNode *root){ 13 bool flag = true; 14 check(root,flag); 15 return flag; 16 }
[3.2]迭代方法
解答4:
1 int maxDepth(TreeNode *root){ 2 if(root==NULL) 3 return 0; 4 return max(maxDepth(root->left),maxDepth(root->right)) + 1; 5 } 6 7 int minDepth(TreeNode *root){ 8 if(root==NULL) 9 return 0; 10 if(root->left==NULL && root->right==NULL) 11 return 1; 12 if(root->left==NULL) 13 return minDepth(root->right)+1; 14 else if(root->right==NULL) 15 return minDepth(root->left)+1; 16 else 17 return min(minDepth(root->left),minDepth(root->right))+1; 18 }
解答5:
检测特定长度的存在性.
1 bool hasPathSum(TreeNode *root,int sum){ 2 if(root==NULL) 3 return false; 4 if(root->left==NULL && root->right==NULL) 5 return sum==root->val; 6 if(root->left && hasPathSum(root->left,sum-root->val)) 7 return true; 8 if(root->right && hasPathSum(root->right,sum-root->val)) 9 return true; 10 return false; 11 }
记录特定长度的路径
1 void dfs(TreeNode *root,int sum,vector<int> path,vector<vector<int> >& res){ 2 if(root==NULL){ 3 return ; 4 } 5 if(root->left==NULL&&root->right==NULL){ 6 if(sum==root->val){ 7 path.push_back(root->val); 8 res.push_back(path); 9 } 10 return; 11 } 12 path.push_back(root->val); 13 dfs(root->left,sum-root->val,path,res); 14 dfs(root->right,sum-root->val,path,res); 15 path.pop_back(); 16 } 17 18 vector<vector<int> > pathSum(TreeNode *root, int sum) { 19 vector<vector<int> > res; 20 vector<int> path; 21 dfs(root,sum,path,res); 22 return res; 23 }
参考
lycc的github代码
时间: 2024-10-22 11:29:42