二分
整数二分
- [acwing] 789 数的范围 理由: 板子题,通过这个题记忆板子。
- [leetcode] 33 搜索旋转排序数组 理由: 在板子的基础上增加了一个弯路:旋转
- [leetcode] 34 在排序数组中查找元素的第一个和最后一个位置 理由: 跟acwing的那个题一样的
- [leetcode] 35 搜索插入位置 理由: 在板子的基础上多了一个弯路:大于最大值的情况
- [leetcode] 69 x的平方根 理由: 看着是小数二分,实际上是整数二分。
- [leetcode] 74 搜索二位矩阵 理由: 以前都是一维的数组中查找,这次查找二维矩阵
- [leetcode] 162 寻找峰值 理由: 考虑判断条件这里有些思维,严格来说也属于板子。
- [leetcode] 275 H制数Ⅱ理由: 稍微有一些难度,要考虑边界情况(不存在的情况)
- [leetcode] 374 猜数字大小 理由: 板子题,多了个交互,注意开Longlong
小数二分
二叉树
遍历问题
- [leetcode] 94 二叉树的中序遍历
二叉树的属性
- 【leetcode】257 二叉树的所有路径
求二叉树的所有路径
/**
* 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:
vector<string> ans;
void dfs(TreeNode* root,string x){
if(!root->left&&!root->right){
x+="->";
x+=to_string(root->val);
ans.push_back(x);
}else{
x+="->";
x+=to_string(root->val);
if(root->left) dfs(root->left,x);
if(root->right) dfs(root->right,x);
}
}
vector<string> binaryTreePaths(TreeNode* root) {
string x=to_string(root->val);
if(!root->left&&!root->right) ans.push_back(x);
if(root->left) dfs(root->left,x);
if(root->right) dfs(root->right,x);
return ans;
}
};
- [leetcode]404 左叶子之和
求二叉树左叶子之和
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
int cnt=0;
if(!root->left&&!root->right) return 0;
if(root->left){
if(!root->left->left&&!root->left->right) cnt+=root->left->val;
}
if(root->left) cnt+=sumOfLeftLeaves(root->left);
if(root->right) cnt+=sumOfLeftLeaves(root->right);
return cnt;
}
};
1.求左右子树的左叶子之和
2.如果当前节点有左叶子,就加上
3.考虑特殊情况:该树只有根节点
- [leetcode]513 找左下角的值
class Solution {
public:
int maxDepth=-1,ans;
int findBottomLeftValue(TreeNode* root) {
dfs(root,1);
return ans;
}
void dfs(TreeNode* root,int depth){
if(depth>maxDepth){
maxDepth=depth;
ans=root->val;
}
if(root->left) dfs(root->left,depth+1);
if(root->right) dfs(root->right,depth+1);
}
};
dfs遍历一遍,然后找到最深的左值更新。
完全二叉树
- 【leetcode】222完全二叉树的节点个数
二叉平衡树
- 【leetcode】110 平衡二叉树
判断一棵树是不是平衡二叉树。
自顶向下的递归:
class Solution {
public:
int height(TreeNode* root) {
if (root == NULL) {
return 0;
} else {
return max(height(root->left), height(root->right)) + 1;
}
}
bool isBalanced(TreeNode* root) {
if (root == NULL) {
return true;
} else {
return abs(height(root->left) - height(root->right)) <= 1 && isBalanced(root->left) && isBalanced(root->right);
}
}
};
这种方法看着很爽,但是时间复杂度为O(n^2)
自底向上的递归:
class Solution {
public:
int height(TreeNode* root) {
if (root == NULL) {
return 0;
}
int leftHeight = height(root->left);
int rightHeight = height(root->right);
if (leftHeight == -1 || rightHeight == -1 || abs(leftHeight - rightHeight) > 1) {
return -1;
} else {
return max(leftHeight, rightHeight) + 1;
}
}
bool isBalanced(TreeNode* root) {
return height(root) >= 0;
}
};
这种方法非常的巧妙,如果这棵树不是二叉平衡树,就返回-1,如果是二叉平衡树,就返回高度,这样等于用同一个函数能返回两种值。
我的写法:
/**
* 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:
bool check(TreeNode* root,int & high){
if(!root) return true;
int l,r;
bool flag=1;
if(!root->left) l=0;
else{
int high;
if(!check(root->left,high)) flag=0;
l=high;
}
if(!root->right) r=0;
else{
int high;
if(!check(root->right,high)) flag=0;
r=high;
}
high=1+max(l,r);
else if(abs(l-r)<=1) return true;
return false;
}
bool isBalanced(TreeNode* root) {
int high;
return check(root,high);
}
};
我是用一个引用来解决不能即返回高度又返回是否的,把高度引用起来,需要控制的条件就是不能提前返回,要把高度计算出来,否则可能空指针异常。