文章目录
有效的字母异位词
题目描述:
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram"
输出: true
示例 2:
输入: s = "rat", t = "car"
输出: false
解题思路:
根据字母异位词的特点,若两个字符串排序后完全相等,则是有效的字母异位词
代码实现:
bool isAnagram(string s, string t)
{
sort(s.begin(), s.end());
sort(t.begin(), t.end());
return s == t;
}
移除元素
题目描述:
给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
给定 nums = [3,2,2,3], val = 3,
函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
定 nums = [0,1,2,2,3,0,4,2], val = 2,
函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
注意这五个元素可为任意顺序。
你不需要考虑数组中超出新长度后面的元素。
解题思路:
调用erase()函数即可
代码实现:
int removeElement(vector<int>& nums, int val)
{
int len = nums.size();
if (len == 0)
{
return 0;
}
auto it = nums.begin();
while (it != nums.end())
{
if (*it == val)
{
//注意这块要及时更新迭代器,否则会造成迭代器失效
it = nums.erase(it);
}
else
{
++it;
}
}
return nums.end() - nums.begin();
}
合并二叉树
题目描述:
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
示例 1:
输入:
Tree 1 Tree 2
1 2
/ \ / \
3 2 1 3
/ \ \
5 4 7
输出:
合并后的树:
3
/ \
4 5
/ \ \
5 4 7
解题思路:
递归
代码实现:
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
if(t1==nullptr)
{
return t2;//将不为空的作为树的新节点
}
if(t2==nullptr)
{
return t1;
}
t1->val+=t2->val;// 两个结点进行合并
t1->left=mergeTrees(t1->left, t2->left);//对左子树进行合并
t1->right=mergeTrees(t1->right, t2->right);//对右子树进行合并
return t1;//返回根结点
}
对称二叉树
题目描述:
给定一个二叉树,检查它是否是镜像对称的。
举例:
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
解题思路:
如果同时满足下面的条件,两个树互为镜像:
- 它们的两个根结点具有相同的值。
- 每个树的右子树都与另一个树的左子树镜像对称。
代码实现:
bool isSymmetric(TreeNode* root1,TreeNode *root2)
{
if(root1==nullptr&&root2==nullptr)
{
return true;
}
if(root1==nullptr||root2==nullptr)
{
return false;
}
if(root1->val!=root2->val)//对应节点值不相等,不是镜像对称
{
return false;
}
return isSymmetric(root1->left,root2->right)
&& isSymmetric(root1->right,root2->left);
}
bool isSymmetric(TreeNode* root)
{
return isSymmetric(root, root);
}
二叉树的最小深度
问题描述:
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最小深度 2.
解题思路:
注意:此题的关键在于递归结束条件
划重点,很多人写出的代码都不符合[1,2]这个测试用例,是因为没搞清楚题意
题目中说明:叶子节点是指没有子节点的节点
这句话的意思是 1 不是叶子节点
递归结束条件:
- 叶子节点的定义:左孩子和右孩子都为NULL时叫做叶子节点
- 当root节点左右孩子都为空时,返回1
- 当root节点左右孩子有一个为空时,返回不为空的孩子节点的深度
- 当root节点左右孩子都不为空时,返回左右孩子较小深度的节点值
代码实现:
int minDepth(TreeNode* root) {
if(root==nullptr)
{
return 0;
}
int left=minDepth(root->left);
int right=minDepth(root->right);
//左孩子为空,右孩子不为空,返回右孩子深度的值加1
if(root->left==nullptr&&root->right!=nullptr)
{
return right+1;
}
//右孩子为空,左孩子不为空,返回左孩子深度的值加1
if(root->left!=nullptr&&root->right==nullptr)
{
return left+1;
}
//两个孩子都不为空,返回左右孩子较小深度的节点值+1
return left<=right?left+1:right+1;
}
};
二叉树的最大深度
题目描述:
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
举例:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最大深度 3 。
解题思路:
DFS
- 找出终止条件:当前节点为空
- 节点为空时说明高度为0,所以返回0;
- 节点不为空时则分别求左右子树的高度的最大值,同时加1表示当前节点的高度,返回该数值
代码描述:
int maxDepth(TreeNode* root) {
if(root==nullptr)
{
return 0;
}
int left=maxDepth(root->left);
int right=maxDepth(root->right);
return left>right?left+1:right+1;//左右子树的高度的最大值加1
}
二叉树的层次遍历 II
题目描述:
给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
举例:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其自底向上的层次遍历为:
[
[15,7],
[9,20],
[3]
]
解题思路:
- 首先按照自上而下的顺序进行层次遍历
- 将该结果进行逆置即可
代码实现:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> res;
if (root == nullptr)
{
return res;
}
queue<TreeNode *> que;
que.push(root);
//层次遍历
while (!que.empty())
{
vector<int> vec;
int size = que.size();
for (int i = 0; i < size; ++i)
{
TreeNode *cur=que.front();
vec.push_back(cur->val)