因为去学别的东西,也就两个月没刷题,结果该忘记的不该忘记的都忘记了。
思来想去,还是做个总结要来的好些。
不涉及那些奇思妙想的题目,就纪录最基本的东西。
文章目录
- 1、引用传参
- 2、快慢指针
- 3、map、set的使用
- 4、其余
- 5、了解vector
1、引用传参
先来看个题目:
等下也是用这个题目
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定数组 nums = [1,1,2],
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
以前只知道指针有这种骚操作,现在知道引用也有这种骚操作了。
2、快慢指针
对于上面这题的题解,便可以采用快慢指针的办法。
不用快慢指针也可以,不过本文不是为了说谁的办法优秀,这题也不能体现出快慢指针的多少优越性,但是重要的是学到这个思路不是吗。
可以考虑一下下面这道题:
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
3、map、set的使用
以下是一个使用set的示例:
给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。
示例 1:
输入:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
输出:
[
[1,0,1],
[0,0,0],
[1,0,1]
]
示例 2:
输入:
[
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
]
输出:
[
[0,0,0,0],
[0,4,5,0],
[0,3,1,0]
]
进阶:
一个直接的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
你能想出一个常数空间的解决方案吗?
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/set-matrix-zeroes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的解法:
void setZeroes(vector<vector<int>>& matrix) {
if(matrix.empty())
return;
int r = matrix.size();
int c = matrix[0].size();
set<int> rs;
set<int> cs;
set<int>::iterator sit;
//将有0的行列提取出来
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
if (matrix[i][j] == 0)
{
rs.insert(j);
cs.insert(i);
}
}
}
if (!cs.empty())
{
int a = c;
vector<int> temp;
while (a > 0)
{
temp.push_back(0);
a--;
}
//将行清零
for (sit = cs.begin(); sit != cs.end(); sit++)
{
matrix[*sit] = temp;
}
}
//将列清零
if (!rs.empty())
{
for (sit = rs.begin(); sit != rs.end(); sit++)
{
for (int k = 0; k< r; k++)
{
matrix[k][*sit] = 0;
}
}
}
}
思路:
接下来是一个map的使用示例:
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"]
输出:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
说明:
所有输入均为小写字母。
不考虑答案输出的顺序。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/group-anagrams
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的解法:
vector<vector<string>> groupAnagrams(vector<string>& strs)
{
vector<vector<string>> res;
map<string,vector<string>> vec;
if(strs.empty()) return res;
for(int i=0;i<strs.size();i++)
{
string temp=strs[i];
sort(temp.begin(),temp.end());
vec[temp].push_back(strs[i]);
}
map<string,vector<string>>::iterator it;
for(auto it=vec.begin();it!=vec.end();it++)
{
res.push_back(it->second);
}
return res;
}
思路:
自己试一题:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
4、其余
其余巧妙设计的题目就不放这里了,今后要是再看到什么好的方法再放进来。
5、了解vector
#include <vector>
using namespace std;
#include<vector>
//创建vector
vector<int> test; //初始化一个Vector实例,用于存放int型数据,实例名字叫test
vector<int> test2 = test; //以test1为标准创建test2
vector<int>test3(10); //像这种,少用。上次用的时候,往里面插了一个数据之后就没办法插入了。何况STL会自己给你分配空间,用不着你操心。
//插入数据
test.insert(test.begin()+i,a); //在第i个元素前插入a
test.insert(test.begin()+i,te2.begin(),te2.end());
//插入一段相同数据类型数据,第一个参数放插入位置(指针/迭代器形式),第二三个参数放待插入元素起始位置
test.push_back(a); //往尾部插入
//一般我们就用尾部插入
//删除元素
test.erase(test.begin());
test.erase(test.begin(),test.begin()+5);//删除区间(第一个元素到第五个元素)
test.clear(); //清空
test.pop_back(); //删除尾部元素
vector<int>::iterator it; //初始化一个vector<int>类型的迭代器
for(it = test.begin();it!=test.end();it++) //从头遍历到尾
{
cout<<*it<<endl; //取出内容
}
//排序
#include<algorithm>
sort(test.begin(),test.end()); //从头到尾,默认从小到大排序
这里要非常注意,前面那个test. 被我注释掉了,因为sort是属于算法范畴,不是容器的类方法。
//一般排序都是要自定义排序的:
bool Comp(const int &a,const int &b)
{
return a>b;
}
sort(test.begin(),test.end(),Comp); //这样就降序排序。
其他还有:
对于二维vector的大小问题、
如vector<vector<int>> ret
:ret中vector的条数:ret.size();
vector的大小:if( ret[0] != NULL ){ int sz = ret[0].size(); }
其他再说吧