赞
踩
给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)
Example
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
[
[3],
[9,20],
[15,7]
]
深度优先搜索(DFS
)
在这个策略中,我们采用深度
作为优先级,以便从跟开始一直到达某个确定的叶子,然后再返回根到达另一个分支。
深度优先搜索策略又可以根据根节点、左孩子和右孩子的相对顺序被细分为先序遍历
,中序遍历
和后序遍历
。
宽度优先搜索(BFS
)
我们按照高度顺序一层一层的访问整棵树,高层次的节点将会比低层次的节点先被访问到。
层次遍历,用变量level
记录当前层数
新的一层只在左边第一个节点处添加
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { vector<vector<int>> res; public: void levelBSTtravel(TreeNode* node,int level) { vector<int> tmp_res; if(level==res.size()) res.push_back(tmp_res); res[level].push_back(node->val); if(node->left) levelBSTtravel(node->left,level+1); if(node->right) levelBSTtravel(node->right,level+1); } vector<vector<int>> levelOrder(TreeNode* root) { if(!root) return res; levelBSTtravel(root,0); return res; } };
给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
queue<TreeNode*> nextLevel
存放下一层的结点
BFS对队列中的层节点遍历
递归,从最后一层逐个返回,追加到res
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ /* ** 递归 ** 从最后一层逐个返回,追加到`res` ** 队列结构存储每一层的节点,因为队列结构是先入先出 ** std::queue http://www.cplusplus.com/reference/queue/queue/?kw=queue ** queue -> empty;front;push;pop;back */ class Solution { vector<vector<int>> res; public: void levelNodeTravel(queue<TreeNode*> curLevel) { vector<int> cur_val; queue<TreeNode*> nextLevel; while(!curLevel.empty()) { TreeNode* tmpNode=curLevel.front();//队头元素 curLevel.pop(); cur_val.push_back(tmpNode->val); if(tmpNode->left) nextLevel.push(tmpNode->left); if(tmpNode->right) nextLevel.push(tmpNode->right); } if(!nextLevel.empty()) levelNodeTravel(nextLevel); res.push_back(cur_val); } vector<vector<int>> levelOrderBottom(TreeNode* root) { queue<TreeNode*> nextLevel; //存放下一层的结点 if(root) { nextLevel.push(root); levelNodeTravel(nextLevel); } return res; } };
Construct queue (public member function )
Test whether container is empty (public member function )
Return size (public member function )
Access next element (public member function )
Access last element (public member function )
Insert element (public member function )
Construct and insert element (public member function )
Remove next element (public member function )
根据一棵树的前序遍历与中序遍历构造二叉树。
Example
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回:
3
/ \
9 20
/ \
15 7
先从先序序列判断根节点,再由根节点确定左右子树
删除先序的根节点遍历下一位(这里通过pre_idx++实现),
递归操作,直至找到叶子节点终止(此时叶子节点的左右区间是空集)
这里需要注意左右区间是左闭右开时,终止条件left==right
.
左闭右闭情形,终止条件是left>right
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ /* ** 递归 ** 先从先序序列判断根节点,再由根节点确定左右子树 ** 删除先序的根节点遍历下一位(这里通过pre_idx++实现), ** 递归操作,直至找到叶子节点终止(此时叶子节点的左右区间是空集) ** 这里需要注意左右区间是左闭右开时,终止条件`left==right`. ** 左闭右闭情形,终止条件是`left>right` */ class Solution { vector<int> preorder; map<int,int> inorder_map; int pre_idx=0; public: TreeNode* helper(int left,int right) { if(left==right) return NULL; TreeNode* root=new TreeNode(preorder[pre_idx]); int inorder_idx=inorder_map[preorder[pre_idx]]; // pre idx -> inorder idx. pre_idx++; // 连接左右子树 root->left=helper(left,inorder_idx); root->right=helper(inorder_idx+1,right); return root; } TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { this->preorder=preorder; for(int i=0;i<inorder.size();i++) inorder_map[inorder[i]]=i; return helper(0,inorder.size()); } };
根据一棵树的中序遍历与后序遍历构造二叉树
先从后序序列逆向判断根节点,再由根节点确定左右子树
注意:这里应该先构建右子树,在构建左子树,负责会出现数组越界
这是因为post_idx在后序遍历数组往前移动(post_idx–)的时候,先指向右子节点的值
删除先序的根节点遍历下一位(这里通过pre_idx++实现),
递归操作,直至找到叶子节点终止(此时叶子节点的左右区间是空集)
这里需要注意左右区间是左闭右开时,终止条件left==right
.
左闭右闭情形,终止条件是left>right
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ /* ** 递归 ** 先从后序序列逆向判断根节点,再由根节点确定左右子树 ** 注意:这里应该先构建右子树,在构建左子树,负责会出现数组越界 ** 这是因为post_idx在后序遍历数组往前移动(post_idx--)的时候,先指向右子节点的值 ** 删除先序的根节点遍历下一位(这里通过pre_idx++实现), ** 递归操作,直至找到叶子节点终止(此时叶子节点的左右区间是空集) ** 这里需要注意左右区间是左闭右开时,终止条件`left==right`. ** 左闭右闭情形,终止条件是`left>right` */ class Solution { vector<int> postorder; map<int,int> inorder_map; int post_idx; public: TreeNode* treeBuild(int left,int right) { if(left==right) return NULL; TreeNode* root=new TreeNode(postorder[post_idx]); int inorder_idx=inorder_map[postorder[post_idx]]; post_idx--; // 构建左右子树 root->right=treeBuild(inorder_idx+1,right); root->left=treeBuild(left,inorder_idx); return root; } TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { this->postorder=postorder; post_idx=postorder.size()-1; for(int i=0;i<inorder.size();i++) inorder_map[inorder[i]]=i; return treeBuild(0,inorder.size()); } };
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
Example:
给定有序数组: [-10,-3,0,5,9],
一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
BFS(广度优先遍历)
区间左闭右开,left==right
说明区间为空,无左右子树
区间长度分为三种情形
length==0
: NULLlength==1
: 一个节点length==2
: 两个节点(一个作为根节点,另一个成为左叶子节点)length>=3
:采用递归,中间值作为根节点。/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ /* ** BFS(广度优先遍历) ** 区间左闭右开,`left==right`说明区间为空,无左右子树 ** 区间长度分为三种情形 `length==0`: NULL `length==1`: 一个节点 `length==2`: 两个节点(一个作为根节点,另一个成为左叶子节点) `length>=3`:采用递归,中间值作为根节点。 */ class Solution { vector<int> nums; public: TreeNode* levelNodeBST(int left,int right) { TreeNode* root=new TreeNode; int length=right-left; if(length==0) return NULL; else if(length==1) root->val=nums[(left+right)/2]; else if(length==2) { root->val=nums[(left+right)/2]; root->left=levelNodeBST(left,(left+right)/2); } else { root->val=nums[(left+right)/2]; root->left=levelNodeBST(left,(left+right)/2); root->right=levelNodeBST((left+right)/2+1,right); } return root; } TreeNode* sortedArrayToBST(vector<int>& nums) { this->nums=nums; return levelNodeBST(0,nums.size()); } };
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ /* ** BFS ** List to vector ** 递归 */ class Solution { vector<int> nums; public: TreeNode* bstHelper(int left,int right) { int length=right-left; TreeNode* root=new TreeNode(0); if(length==0) return NULL; else if(length==1) root->val=nums[(left+right)/2]; else if(length==2) { root->val=nums[(left+right)/2]; root->left=bstHelper(left,(left+right)/2); } else { root->val=nums[(left+right)/2]; root->left=bstHelper(left,(left+right)/2); root->right=bstHelper((left+right)/2+1,right); } return root; } TreeNode* sortedListToBST(ListNode* head) { // if(!head) return NULL; while(head) // list 2 vector { nums.push_back(head->val); head=head->next; } return bstHelper(0,nums.size()); } };
slow_ptr
和 fast_ptr
。slow_ptr
每次向后移动一个节点而 fast_ptr
每次移动两个节点。当 fast_ptr
到链表的末尾时 slow_ptr
就访问到链表的中间元素。对于一个偶数长度的数组,中间两个元素都可用来作二叉搜索树的根。prev_ptr
的指针记录 slow_ptr
之前的元素,也就是满足 prev_ptr.next
= slow_ptr
。断开左侧部分就是让 prev_ptr.next = None
。slow_ptr.next
作为头指针。private ListNode findMiddleElement(ListNode head) { // The pointer used to disconnect the left half from the mid node. ListNode prevPtr = null; ListNode slowPtr = head; ListNode fastPtr = head; // Iterate until fastPr doesn't reach the end of the linked list. while (fastPtr != null && fastPtr.next != null) { prevPtr = slowPtr; slowPtr = slowPtr.next; fastPtr = fastPtr.next.next; } // Handling the case when slowPtr was equal to head. if (prevPtr != null) { prevPtr.next = null; } return slowPtr; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。