第八天 2021-3-10 每日刷四题
刷题模块:树 - 简单难度
一、【题】相同的树
直接递归地扫描整个树即可
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(p!=nullptr && q!=nullptr && p->val!=q->val) return false;
else if((p==nullptr && q!=nullptr) || (p!=nullptr && q==nullptr)) return false;
else if(p==nullptr && q==nullptr) return true;
return (isSameTree(p->left,q->left) && isSameTree(p->right,q->right));
}
};
官方解法,对if判断条件的正确排列省去大量判断
1. 模式识别:多个if判断条件并列时,注意顺序
if (A && B){}
else if (A || B){}
else {!A && !B}
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if (p == nullptr && q == nullptr) {
return true;
} else if (p == nullptr || q == nullptr) {
return false;
} else if (p->val != q->val) {
return false;
} else {
return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
}
};
二、STL:queue
函数 | 方法 |
---|---|
pop() | 仅仅删除第一个元素,并不返回,要和front()搭配使用 |
下面有非常好的解释,如果提取的同时删除,提取的元素被接收失败,那么数据就丢失了,所以将提取和删除功能分开。
为什么C++中stack/queue的pop()函数不返回值而返回void
三、STL:deque
四、【题】对称二叉树
迭代法求解
class Solution {
public:
bool isSymmetric(TreeNode* root) {
queue<TreeNode*> tree;
TreeNode* left=nullptr,*right=nullptr;
tree.push(root->left);
tree.push(root->right);
while(!tree.empty()){
left=tree.front();
tree.pop();
right=tree.front();
tree.pop();
if(left==nullptr && right==nullptr){
continue;
}else if(left==nullptr || right==nullptr){
return false;
}else if(left->val!=right->val){
return false;
}
tree.push(left->left);
tree.push(right->right);
tree.push(left->right);
tree.push(right->left);
}
return true;
}
};
递归法求解
从此题可以看到,如果题目所给函数参数和返回值无法满足要求,可以使用这种方法重新建立符合要求的函数。
(p==nullptr && q==nullptr)
简化为
(!p && !q)
class Solution {
public:
bool check(TreeNode *p, TreeNode *q) {
if (!p && !q) return true;
if (!p || !q) return false;
return p->val == q->val && check(p->left, q->right) && check(p->right, q->left);
}
bool isSymmetric(TreeNode* root) {
return check(root, root);
}
};
这里重写函数后,比迭代方法简单多了.
五、【题】二叉树的最大深度
基础题
class Solution {
public:
int maxDepth(TreeNode* root) {
if(!root) return 0;
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
};
六、【题】将有序数组转换为二叉搜索树
初步预想构建AVL树,但是实际上并没有那么复杂
由于数组初始已经有序,所以每次只要选择中间数作为根节点即可
1.模式识别:遇到会写但解法很离谱的题,多读几遍题
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
return helper(nums, 0, nums.size() - 1);
}
TreeNode* helper(vector<int>& nums, int left, int right) {
if (left > right) {
return nullptr;
}
// 总是选择中间位置左边的数字作为根节点
int mid = (left + right) / 2;
TreeNode* root = new TreeNode(nums[mid]);
root->left = helper(nums, left, mid - 1);
root->right = helper(nums, mid + 1, right);
return root;
}
};
方法一:中序遍历,总是选择中间位置左边的数字作为根节点
int mid = (left + right) / 2;
方法二:中序遍历,总是选择中间位置右边的数字作为根节点
int mid = (left + right + 1) / 2;
方法三:中序遍历,选择任意一个中间位置数字作为根节点
int mid = (left + right + rand.nextInt(2)) / 2;