二叉树与递归
一、二叉树相关的定义
- 完全二叉树:除了最后一层所有层的节点数达到最大
- 满二叉树:所有层的节点数达到最大
- 平衡二叉树:每个节点的左右子树的高度差不超过1
- 二分搜索数:每个节点的左子节点小于等于该节点,右子节点大于该节点
二、递归的两个部分
#include <iostream>
#include <vector>
#include <queue>
#include <string>
#include <stack>
#include <assert.h>
#include <stdexcept>
#include <limits.h>
#include <unordered_set>
#include <unordered_map>
#include <functional>
#include <math.h>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution1 {
public:
int maxDepth(TreeNode* root) {
if (root == NULL)
return 0;
return max(maxDepth(root->left), maxDepth(root->right)) + 1;
}
};
class Solution2 {
public:
int minDepth(TreeNode* root) {
if (root == NULL)
return 0;
if (root->left != NULL&&root->right != NULL) {
return min(minDepth(root->left), minDepth(root->right)) + 1;
}
else if (root->left != NULL) {
return minDepth(root->left) + 1;
}
else if (root->right != NULL) {
return minDepth(root->right) + 1;
}
else {
return 1;
}
}
};
class Solution3 {
public:
TreeNode* invertTree(TreeNode* root) {
if (root == NULL)
return NULL;
root->left = invertTree(root->left);
root->right = invertTree(root->right);
swap(root->left, root->right);
return root;
}
};
class Solution4 {
public:
bool isSameTree(TreeNode *p, TreeNode *q) {
if (p == NULL && q == NULL)
return true;
else if (p != NULL && q != NULL) {
if (p->val == q->val && isSameTree(p->left, q->left) && isSameTree(p->right, q->right))
return true;
else
return false;
} else
return false;
}
};
class Solution5 {
public:
bool isSymmetric(TreeNode* root) {
if (root == NULL)
return true;
return isSymmetric(root->left, root->right);
}
static bool isSymmetric(TreeNode* p, TreeNode* q) {
if (p == NULL && q == NULL)
return true;
if (p != NULL && q != NULL) {
if (p->val == q->val) {
if (isSymmetric(p->left, q->right) && isSymmetric(p->right, q->left))
return true;
else
return false;
}
else return false;
}
else
return false;
}
};
class Solution6 {
public:
int countNodes(TreeNode* root) {
int res = 0;
while (root != NULL) {
int leftDepth = depth(root->left);
int rightDepth = depth(root->right);
if (leftDepth == rightDepth) {
res += pow(2, leftDepth);
root = root->right;
}
else {
res += pow(2, rightDepth);
root = root->left;
}
}
return res;
}
static int depth(TreeNode* root) {
if (root == NULL)
return 0;
return depth(root->left) + 1;
}
};
class Solution7 {
public:
bool isBalanced(TreeNode* root) {
if (root == NULL)
return true;
int t = depth(root->left) - depth(root->right);
if (t >= -1 && t <= 1 && isBalanced(root->left) && isBalanced(root->right))
return true;
else return false;
}
static int depth(TreeNode* node) {
if (node == NULL)
return 0;
return max(depth(node->left) + 1, depth(node->right) + 1);
}
};
class Solution8 {
public:
bool hasPathSum(TreeNode* root, int sum) {
if (root == NULL)
return false;
if (root->left == NULL && root->right == NULL) {
if (root->val == sum)
return true;
else
return false;
}
return (hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val));
}
};
class Solution9 {
public:
int sumOfLeftLeaves(TreeNode* root) {
if (root == NULL)
return 0;
int res = 0;
if (root->left != NULL)
if (root->left->left == NULL && root->left->right == NULL)
res += root->left->val;
res += sumOfLeftLeaves(root->left);
res += sumOfLeftLeaves(root->right);
return res;
}
};
class Solution10 {
public:
vector<string> binaryTreePaths(TreeNode* root) {
if (root == NULL)
return vector<string>();
vector<string> res;
if (root->left == NULL && root->right == NULL) {
res.push_back(to_string(root->val));
return res;
}
vector<string> leftS = binaryTreePaths(root->left);
for (int i = 0; i < leftS.size(); i++) {
res.push_back(to_string(root->val) + "->" + leftS[i]);
}
vector<string> rightS = binaryTreePaths(root->right);
for (int i = 0; i < rightS.size(); i++) {
res.push_back(to_string(root->val) + "->" + rightS[i]);
}
return res;
}
};
class Solution11 {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> res_tmp = _pathSum(root, sum);
vector<vector<int>> res= res_tmp;
for (int i = 0; i < res_tmp.size(); i++) {
int len = res_tmp[i].size();
for (int j = 0; j < len; j++) {
res[i][j] = res_tmp[i][len - 1 - j];
}
}
return res;
}
static vector<vector<int>> _pathSum(TreeNode* root, int sum) {
if (root == NULL)
return vector<vector<int>>();
vector<vector<int>> res;
if (root->left == NULL && root->right == NULL && root->val == sum) {
vector<int> path;
path.push_back(root->val);
res.push_back(path);
}
vector<vector<int>> leftPath = _pathSum(root->left, sum - root->val);
for (int i = 0; i < leftPath.size(); i++) {
leftPath[i].push_back(root->val);
}
vector<vector<int>> rightPath = _pathSum(root->right, sum - root->val);
for (int i = 0; i < rightPath.size(); i++) {
rightPath[i].push_back(root->val);
}
for (int i = 0; i < leftPath.size(); i++) {
res.push_back(leftPath[i]);
}
for (int i = 0; i < rightPath.size(); i++) {
res.push_back(rightPath[i]);
}
return res;
}
};
class Solution12 {
public:
int sumNumbers(TreeNode* root) {
vector<vector<int>> resVec = _sumNumbers(root);
int res = 0;
for (int i = 0; i < resVec.size(); i++) {
for (int j = 0; j < resVec[i].size(); j++) {
res += resVec[i][j] * pow(10, j);
}
}
return res;
}
vector<vector<int>> _sumNumbers(TreeNode* root) {
if (root == NULL)
return vector<vector<int>>();
vector<vector<int>> res;
if (root->left == NULL && root->right == NULL) {
vector<int> path;
path.push_back(root->val);
res.push_back(path);
}
vector<vector<int>> leftPath = _sumNumbers(root->left);
for (int i = 0; i < leftPath.size(); i++) {
vector<int> tmp = leftPath[i];
tmp.push_back(root->val);
res.push_back(tmp);
}
vector<vector<int>> rightPath = _sumNumbers(root->right);
for (int i = 0; i < rightPath.size(); i++) {
vector<int> tmp = rightPath[i];
tmp.push_back(root->val);
res.push_back(tmp);
}
return res;
}
};
class Solution13 {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == NULL)
return NULL;
if (p->val < root->val && q->val < root->val)
return lowestCommonAncestor(root->left, p, q);
if (p->val > root->val && q->val > root->val)
return lowestCommonAncestor(root->right, p, q);
return root;
}
};
class Solution14 {
public:
bool isValidBST(TreeNode* root) {
if (root == NULL)
return false;
vector<int> resVec = inOrder(root);
for (int i = 1; i < resVec.size(); i++) {
if (resVec[i] <= resVec[i - 1])
return false;
}
return true;
}
static vector<int> inOrder(TreeNode* root) {
if (root == NULL)
return vector<int>();
vector<int> res;
vector<int> resLeft = inOrder(root->left);
for (int i = 0; i < resLeft.size(); i++)
res.push_back(resLeft[i]);
res.push_back(root->val);
vector<int> resRight = inOrder(root->right);
for (int i = 0; i < resRight.size(); i++)
res.push_back(resRight[i]);
return res;
}
};
class Solution15 {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
TreeNode* res = arrayToBST(nums, 0, nums.size()-1);
return res;
}
TreeNode* arrayToBST(vector<int>& nums, int begin, int end) {
if (begin > end)
return NULL;
int mid = begin + (end - begin) / 2;
TreeNode* res = new TreeNode(nums[mid]);
res->left = arrayToBST(nums, begin, mid - 1);
res->right = arrayToBST(nums, mid + 1, end);
return res;
}
};
class Solution16 {
public:
int kthSmallest(TreeNode* root, int k) {
vector<int> res;
_inOrder(root, k, res);
return res[k - 1];
}
void _inOrder(TreeNode* root, int k, vector<int>& res) {
if (root == NULL)
return;
_inOrder(root->left, k, res);
res.push_back(root->val);
if (res.size() >= k)
return;
_inOrder(root->right, k, res);
return;
}
};