对称二叉树
解题思路,递归和迭代分别代表着深度搜索(DFS)和广度搜索(BFS)。
深度搜索用栈或递归,需要明白如何递归,因为判断是否镜像对称,所以在递归的时候需要交换节点的左右节点进行递归。
广度搜索用队列,利用队列获得每一层的数字,其中在节点为null时也需要记录,然后判断该数组是否是一个回文串。
AC代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
//BFS
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(root == NULL) return true;
queue<TreeNode*> qtn;
qtn.push(root);
while(qtn.size() != 0) {
int n = qtn.size();
vector<int> vi;
for(int i = 0; i < n; ++i) {
TreeNode* ope = qtn.front();
qtn.pop();
if(ope->left) {
qtn.push(ope->left);
vi.push_back(ope->left->val);
}
else vi.push_back(INT_MAX);
if(ope->right) {
qtn.push(ope->right);
vi.push_back(ope->right->val);
}
else vi.push_back(INT_MAX);
}
vector<int> tmp = vi;
reverse(vi.begin(), vi.end());
if(tmp != vi) return false;
}
return true;
}
};
//DFS
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if (root == nullptr) return true;
return dfs(root->left, root->right);
}
bool dfs(TreeNode* root1, TreeNode* root2) {
if (root1 == nullptr && root2 == nullptr) return true;
if (root1 == nullptr || root2 == nullptr || root1->val != root2->val) return false;
return dfs(root1->left, root2->right) && dfs(root1->right, root2->left);
}
};
二叉树的层序遍历
解题思路,这道题的标签是中等,上一道题是简单。不清楚这个是按什么定位的。这道题就是利用队列对数进行bfs,也没有什么需要注意的问题。
AC代码:
/**
* 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:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(root == NULL) return res;
queue<TreeNode*> qtn;
qtn.push(root);
while(!qtn.empty()) {
vector<int> vi;
for(int n = qtn.size(); n > 0; --n) {
TreeNode* ope = qtn.front();
qtn.pop();
vi.push_back(ope->val);
if(ope->left) qtn.push(ope->left);
if(ope->right) qtn.push(ope->right);
}
res.push_back(vi);
}
return res;
}
};
二叉树的锯齿形层次遍历
解题思路,这道题和上一道题的方法一样,用 bfs 搜索实现层次遍历,设置一个标志位实现锯齿形。
AC代码:
/**
* 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:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
vector<vector<int>> res;
if(root == NULL) return res;
bool flag = false;
queue<TreeNode*> qtn;
qtn.push(root);
while(!qtn.empty()) {
vector<int> vi;
for(int n = qtn.size(); n > 0; --n) {
TreeNode* ope = qtn.front();
qtn.pop();
vi.push_back(ope->val);
if(ope->left) qtn.push(ope->left);
if(ope->right) qtn.push(ope->right);
}
if(flag) reverse(vi.begin(), vi.end());
res.push_back(vi);
flag = flag ^ 1;
}
return res;
}
};
二叉树的最大深度
解题思路,还是一样的 bfs,每遍历一次,深度加 1。也可以利用 dfs 遍历。
AC代码:
/**
* 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 maxDepth(TreeNode* root) {
int res;
if(root == NULL) return 0;
queue<TreeNode*> qtn;
qtn.push(root);
while(!qtn.empty()) {
for(int n = qtn.size(); n > 0; --n) {
TreeNode* ope = qtn.front();
qtn.pop();
if(ope->left) qtn.push(ope->left);
if(ope->right) qtn.push(ope->right);
}
++res;
}
return res;
}
};
//dfs
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == nullptr) return 0;
return max(maxDepth(root->left), maxDepth(root->right)) + 1;
}
};
从前序与中序遍历序列构造二叉树
解题思路,利用递归的思想,构件根节点以及左右节点。
AC代码:
/**
* 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 {
unordered_map<int, int> index;
public:
TreeNode* myBuildTree(const vector<int>& preorder, const vector<int>& inorder, int preorder_left, int preorder_right, int inorder_left, int inorder_right) {
if (preorder_left > preorder_right) {
return nullptr;
}
int preorder_root = preorder_left;
int inorder_root = index[preorder[preorder_root]];
TreeNode* root = new TreeNode(preorder[preorder_root]);
int size_left_subtree = inorder_root - inorder_left;
root->left = myBuildTree(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1);
root->right = myBuildTree(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size() != inorder.size()) return nullptr;
int n = preorder.size();
for (int i = 0; i < n; ++i) {
index[inorder[i]] = i;
}
return myBuildTree(preorder, inorder, 0, n - 1, 0, n - 1);
}
};
从中序与后序遍历序列构造二叉树
解题思路,和上一道题一样,利用递归构造的思想构造树。
AC代码:
/**
* 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 {
unordered_map<int, int> index;
public:
TreeNode* myBuildTree(vector<int>& inorder, vector<int>& postorder, int inorder_l, int inorder_r, int postorder_l, int postorder_r) {
if(inorder_l > inorder_r) return NULL;
int postorder_root = postorder_r;
int inorder_root = index[postorder[postorder_root]];
TreeNode* root = new TreeNode(postorder[postorder_root]);
int size_left = inorder_root - inorder_l;
root->left = myBuildTree(inorder, postorder, inorder_l, inorder_root-1, postorder_l, postorder_l+size_left-1);
root->right = myBuildTree(inorder, postorder, inorder_root+1, inorder_r, postorder_l+size_left, postorder_r-1);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.size() != postorder.size()) return NULL;
int n = inorder.size();
for(int i = 0; i < n; ++i) {
index[inorder[i]] = i;
}
return myBuildTree(inorder, postorder, 0, n-1, 0, n-1);
}
};
二叉树的层次遍历 II
解题思路,一样的使用队列进行广度搜索实现。
AC代码:
/**
* 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:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> res;
queue<TreeNode* > qtn;
if(root)qtn.push(root);
while(qtn.size() != 0) {
vector<int> tmp;
for(int n = qtn.size(); n > 0; --n) {
TreeNode* r = qtn.front(); qtn.pop();
tmp.push_back(r->val);
if(r->left) qtn.push(r->left);
if(r->right) qtn.push(r->right);
}
res.insert(res.begin(),tmp);
}
return res;
}
};
将有序数组转换为二叉搜索树
解题思路,这道题的答案不是唯一的,但是得清除平衡二叉搜索树的概念,如何去构造,首先想到的就是寻找中位数,然后递归寻找左右两边的中位数,这样就可以构造出一棵高度平衡的二叉搜索树。
AC代码:
/**
* 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* findMid(vector<int>& nums, int start, int end) {
if(start > end) return NULL;
int mid = (end - start) / 2 + start;
TreeNode* root = new TreeNode(nums[mid]);
root->left = findMid(nums, start, mid-1);
root->right = findMid(nums, mid+1, end);
return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
return findMid(nums, 0, nums.size()-1);
}
};
有序链表转换二叉搜索树
解题思路,简单一点的就是利用上一道题的思路,将链表转成数组,然后递归寻找中位数建树。为了不用同一种思路,后面借鉴了解题,解决这道题可以利用完全二叉树的思想,即父节点与其左右节点的关系建树。若父节点为 i ,则其左右节点为 2i 和 2i+1。利用这个性质就可以利用递归建树然后插入数实现完全平衡二叉树。
AC代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
ListNode* ope;
TreeNode* transMid(int index, int n) {
if(index>n) return nullptr;
TreeNode* root = new TreeNode();
root->left = transMid(index*2,n);
if(ope == nullptr) return nullptr;
root->val = ope->val;
ope = ope->next;
root->right = transMid(index*2+1,n);
return root;
}
TreeNode* sortedListToBST(ListNode* head) {
if(head == nullptr) return nullptr;
ope = head;
int len = 0;
for(;head != nullptr; ++len, head = head->next);
return transMid(1, len);
}
};
平衡二叉树
解题思路,判断一棵树是否为平衡二叉树,关键在于遍历树的每个节点,然后判断该节点的左右子树的高度差的绝对值是不是大于1。
AC代码:
/**
* 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 maxDeep(TreeNode* root) {
if (root == NULL) return 0;
return max(maxDeep(root->left), maxDeep(root->right)) + 1;
}
bool isBalanced(TreeNode* root) {
if(root == NULL) return true;
queue<TreeNode*> qtn;
qtn.push(root);
while(!qtn.empty()) {
for(int i = qtn.size(); i > 0; --i) {
if(abs(maxDeep(qtn.front()->left) - maxDeep(qtn.front()->right)) > 1) return false;
if(qtn.front()->left)qtn.push(qtn.front()->left);
if(qtn.front()->right) qtn.push(qtn.front()->right);
qtn.pop();
}
}
return true;
}
};