【刷题】D1
- 先记录之前做过的题
- 今天做的题目
- [LC49 字母异位词分组](https://leetcode.cn/problems/group-anagrams/description/)
- [LC438 找到字符串中所有字母异位词](https://leetcode.cn/problems/find-all-anagrams-in-a-string/)
- [LC349 两个数组的交集](https://leetcode.cn/problems/intersection-of-two-arrays/)
- [LC350 两个数组的交集2](https://leetcode.cn/problems/intersection-of-two-arrays-ii/)
先记录之前做过的题
虽然写着D1,但其实还是写了几道题目了。其实之前也做了不少题目,但是因为各种各样原因,都没有保持连续性。所以决定开始记录一下刷题的过程,督促自己准备秋招。
根据代码随想录顺序
LC704 二分查找
LC35 搜索插入位置
LC34 在排序数组中查找元素的第一个和最后一个位置
LC69 x的平方根
LC367 有效的完全平方数
LC27 移除元素
LC26 删除有序数组中的重复项
LC283 移动零
LC844 比较含退格的字符串
LC977 有序数组的平方
LC209 长度最小的子数组
LC904 水果成篮
LC76 最小覆盖子串
LC59 螺旋矩阵2
LC54 螺旋矩阵
LC剑指29 顺时针打印矩阵
LC203 移除链表元素
LC707 设计链表
LC206 反转链表
LC24 两两交换链表中的节点
LC19 删除链表的倒数第N个节点
LC面试题02.07 链表相交
LC142 环形链表2
LC242 有效的字母异位词
LC383 赎金信
今天做的题目
LC49 字母异位词分组
这是一个M题,但是好像用哈希表的思想能够比较简单就实现了。哈希表定义为vector<vector<string>>
首先将输入的字符串遍历,根据排序后的字符串为key,将原来的字符串作为value输入到哈希表中。
然后对哈希表进行遍历,将不同key的value都输出到ans中。
代码如下:
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> ans;
unordered_map<string,vector<string>> umap;
for(auto str:strs){
string temp=str;
sort(temp.begin(),temp.end());
umap[temp].push_back(str);
}
for(auto x:umap){
ans.push_back(x.second);
}
return ans;
}
};
LC438 找到字符串中所有字母异位词
尝试了暴力,我太愚蠢了…结果当然是超时了
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> ans;
int n=p.size();
sort(p.begin(),p.end());
for(int i=0;i+n<=s.size();i++){
string str=s.substr(i,n);
sort(str.begin(),str.end());
if(str==p){
ans.push_back(i);
}
}
return ans;
}
};
看了眼题解,用滑动窗口。记住,子串问题用滑动窗口。
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
unordered_map<char,int> need,window;
vector<int> ans;
for(auto c:p){
need[c]++;
}
int left=0, right=0;
int valid=0;
while(right<s.size()){
char c=s[right];//向右移动窗口
right++;
if(need.count(c)){//当前进入窗口的字符是需要的
window[c]++;
if(window[c]==need[c]){//如果这个字符的数量达到了need的数量
valid++;
}
}
while(right-left>=p.size()){//缩小左边的边界
if(valid==need.size()){//满足要求
ans.push_back(left);
}
char d=s[left];//需要移除的字符
left++;
if(need.count(d)){//如果这个字符在need中,需要删掉
if(need[d]==window[d]){
valid--;
}
window[d]--;
}
}
}
return ans;
}
};
LC349 两个数组的交集
这题比较简单,对第一个数组哈希表之后,用第二个数组看表中是否有自己的字符。这里哈希表可以用数组来表示。然后用unordered_map来记录结果。
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
vector<int> ans;
int hash[1001]={0};
for(int num:nums1){
hash[num]++;
}
unordered_map<int,int> umap;
for(int num:nums2){
if(hash[num]>0){
umap[num]++;
}
}
for(auto x:umap){
ans.push_back(x.first);
}
return ans;
}
};
其实用unordered_set也可以。
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
vector<int> ans;
int hash[1001]={0};
for(int num:nums1){
hash[num]++;
}
unordered_set<int> uset;
for(int num:nums2){
if(hash[num]>0){
uset.insert(num);
}
}
for(auto x:uset){
ans.push_back(x);
}
return ans;
//或者把上面一段改为
//return vector<int>(uset.begin().uset.end());
}
};
LC350 两个数组的交集2
自己的写法。先统计两个数组的哈希表,然后进行比较,留下较小的值。然后将字符出现大于0的放到umap中,最后根据字符最小出现次数打印到ans中。
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
int hash1[1001]={0};
int hash2[1001]={0};
vector<int> ans;
for(int x:nums1){
hash1[x]++;
}
for(int x:nums2){
hash2[x]++;
}
unordered_map<int,int> umap;
for(int x:nums2){
hash2[x]=min(hash1[x],hash2[x]);
if(hash2[x]>0){
umap[x]=hash2[x];
}
}
for(auto x:umap){
while(x.second--){
ans.push_back(x.first);
}
}
return ans;
}
};
优化一下,不用两个数组作为hash,直接用umap。
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
vector<int> ans;
unordered_map<int,int> umap;
for(auto x:nums1){
umap[x]++;
}
for(auto x:nums2){
if(umap.count(x) && umap[x]>0){
ans.push_back(x);
umap[x]--;
// if(umap[x]==0) umap.erase(x);
}
}
return ans;
}
};
看了题解,还有双指针的方法
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
sort(nums1.begin(),nums1.end());
sort(nums2.begin(),nums2.end());
vector<int> ans;
int left=0, right=0;
while(left<nums1.size() && right<nums2.size()){
if(nums1[left]<nums2[right]){
left++;
}
else if(nums1[left]>nums2[right]){
right++;
}
else{
ans.push_back(nums1[left]);
left++;
right++;
}
}
return ans;
}
};