- 从中序与后序遍历序列构造二叉树
根据一棵树的中序遍历与后序遍历构造二叉树。
和上一题基本一致,这里注意两点:后序遍历根节点永远在最后,后序遍历从后往前是先右子树后左子树,由此可得解
/**
* 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 {
public:
TreeNode *buildTree(vector<int>& inorder, vector<int>& postorder) {
int pos = postorder.size() - 1;
return buildTree(postorder, pos, inorder, 0, inorder.size() - 1);
}
TreeNode *buildTree(vector<int>& postorder, int& pos, vector<int>& inorder, int left, int right)
{
if (pos >= postorder.size())
return 0;
int i = left;
// 搜索到目前的根在中序的位置i
for (; i <= right; ++i)
{
if (inorder[i] == postorder[pos])
break;
}
// 当前的根为前序的pos
TreeNode* node = new TreeNode(postorder[pos]);
// 当右边只剩一个就不用递归了
if (i + 1 <= right)
node->right = buildTree(postorder, --pos, inorder, i + 1, right); // 右子树
// 当左边只剩一个就不用递归了
if (left <= i - 1)
node->left = buildTree(postorder, --pos, inorder, left, i - 1); // 左子树
return node;
}
};
- 二叉树的层次遍历2
给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
和之前的并无区别,最后对vector进行反转即可
/**
* 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>> ret;
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
search(root, 0);
reverse(ret.begin(), ret.end());
return ret;
}
void search(TreeNode *root, int height)
{
if (root == NULL)
return;
if (height == ret.size())
ret.resize(height + 1);
ret[height].push_back(root->val);
height++;
search(root->left, height);
search(root->right, height);
}
};
- 将有序数组转换为二叉搜索树
本题解法不唯一,在此采用的策略是去中间点为根,左边为左子树右边为右子树
/**
* 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 {
public:
TreeNode *sortedArrayToBST(vector<int>& nums) {
return makeTree(nums, 0, nums.size());
}
TreeNode *makeTree(vector<int> &nums, int left, int right)
{
if (left == right)
return NULL;
int mid = (left + right) / 2;
TreeNode *root = new TreeNode(nums[mid]);
root->left = makeTree(nums, left, mid);
root->right = makeTree(nums, mid + 1, right);
return root;
}
};
- 有序链表转二叉搜索树
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
本题和上题的区别在于链表不方便索引。这里有两种方法:一种是采取快慢指针每次找到中间节点,另一种是将链表转存在数组中。是要空间还是时间就看需求了
/**
* 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) {}
* };
*/
class Solution {
public:
TreeNode* sortedListToBST(ListNode* head) {
return buildTree(head, nullptr);
}
TreeNode * buildTree(ListNode* head, ListNode * tail){
if(head == tail) return nullptr;
ListNode* slow = head, *fast = head;
while(fast != tail && fast->next != tail){
slow = slow->next;
fast = fast->next->next;
}
TreeNode * root = new TreeNode(slow->val);
root->left = buildTree(head, slow);
root->right = buildTree(slow->next, tail);
return root;
}
};
class Solution {
public:
TreeNode* sortedListToBST(ListNode* head) {
vector<int> v;
while(head != nullptr){
v.push_back(head->val);
head = head->next;
}
return buildTree(v, 0, v.size());
}
TreeNode * buildTree(vector<int> & v, int begin, int end){
if(begin == end) return nullptr;
int middle = (begin+end)/2;
TreeNode * root = new TreeNode(v[middle]);
root->left = buildTree(v, begin, middle);
root->right = buildTree(v, middle+1, end);
return root;
}
};
- 平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。
一个平衡二叉树要求所有子树均为平衡二叉树,所以我们可以利用递归检测每一个子树是否满足要求,有一个不满足则为假。具体到实现有两种选择:第一种是自顶向下,比较当前情况然后再检查子树是否满足,第二种是自底向上,先去递归到最小子树看是否满足,再依次往上比较
/**
* 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 {
private:
// Recursively obtain the height of a tree. An empty tree has -1 height
int height(TreeNode* root) {
// An empty tree has height -1
if (root == NULL) {
return -1;
}
return 1 + max(height(root->left), height(root->right));
}
public:
bool isBalanced(TreeNode* root) {
// An empty tree satisfies the definition of a balanced tree
if (root == NULL) {
return true;
}
// Check if subtrees have height within 1. If they do, check if the
// subtrees are balanced
return abs(height(root->left) - height(root->right)) < 2 &&
isBalanced(root->left) &&
isBalanced(root->right);
}
};
class Solution {
private:
// Return whether or not the tree at root is balanced while also storing
// the tree's height in a reference variable.
bool isBalancedTreeHelper(TreeNode* root, int& height) {
// An empty tree is balanced and has height = -1
if (root == NULL) {
height = -1;
return true;
}
// Check subtrees to see if they are balanced. If they are, check if the
// current node is also balanced using the heights obtained from the
// recursive calls.
int left, right;
if (isBalancedTreeHelper(root->left, left) &&
isBalancedTreeHelper(root->right, right) &&
abs(left - right) < 2) {
// Store the current tree's height
height = max(left, right) + 1;
return true;
}
return false;
}
public:
bool isBalanced(TreeNode* root) {
int height;
return isBalancedTreeHelper(root, height);
}
};
- 二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。说明: 叶子节点是指没有子节点的节点。
本题最大的坑在于最小深度的定义上:定义为到叶子节点的距离,因此需要考虑当仅有一个叶子的时候不需要再去比较另一个分支
/**
* 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 {
public:
int minDepth(TreeNode* root) {
if (root == NULL)
return 0;
if (root->left == NULL)
return 1 + minDepth(root->right);
else if (root->right == NULL)
return 1 + minDepth(root->left);
else
return 1 + min(minDepth(root->left), minDepth(root->right));
}
};
- 路径总和
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
遍历的过程中加上一个值的判断即可
/**
* 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 {
public:
bool hasPathSum(TreeNode* root, int sum) {
if (root == NULL)
return false;
sum -= root->val;
if (root->left == NULL && root->right == NULL)
{
if (sum == 0)
return true;
else return false;
}
return hasPathSum(root->left, sum) || hasPathSum(root->right, sum);
}
};