【数据结构/哈希表】题解+备注
242.有效的字母异位词
class Solution {
public:
// 使用数组计数
bool isAnagram(string s, string t) {
vector<int> sArr(26);
// 记录字符串s的各字符数量
for(char c : s){
sArr[c - 'a']++;
}
// 进行各字符数量的匹配
for(char c : t){
if(sArr[c- 'a'] == 0) return false;
sArr[c- 'a']--;
}
// 最后校验是否所有字符都完全匹配到了
return accumulate(sArr.begin(),sArr.end(),0) == 0;
}
};
383.赎金信
class Solution {
public:
// 使用数组计数
bool canConstruct(string ransomNote, string magazine) {
int unmap[26] = {0};
// 记录字符串magazine的字符数量
for(char c : magazine){
unmap[c - 'a']++;
}
// 进行匹配
for(char c : ransomNote){
unmap[c-'a']--;
if(unmap[c-'a'] < 0) return false;
}
return true;
}
};
49.字母异位词分组
class Solution {
public:
// 通过关联式容器计数
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string, vector<string>> mp;
// 统计各个字符串的数量
for (string& str: strs) {
string key = str;
sort(key.begin(), key.end());
mp[key].emplace_back(str);
}
// 返回答案
vector<vector<string>> ans;
for (auto it = mp.begin(); it != mp.end(); ++it) {
ans.emplace_back(it->second);
}
return ans;
}
};
438.找到字符串中所有字母异位词
class Solution {
public:
// 使用数据进行计数,并配合滑动窗口思想
vector<int> findAnagrams(string s, string p) {
int slen = s.size();
int plen = p.size();
if(slen < plen) return{};
vector<int> sArr(26);
vector<int> pArr(26);
vector<int> ans;
// 统计p的字符数量
for(char c : p){
pArr[c - 'a']++;
}
// 初始化第一个窗口
for(int i{};i<plen;++i){
sArr[s[i] - 'a']++;
}
if(sArr == pArr) ans.emplace_back(0);
// 开始进行窗口移动
for(int i = 0;i< slen - plen;++i){
sArr[s[i] - 'a']--; // 窗口左边界右移
sArr[s[i + plen] - 'a']++;// 窗口扩展右边界
if(sArr == pArr) ans.emplace_back(i+1);
}
return ans;
}
};
349.两个数组的交集
class Solution {
public:
// 使用关联式容器计数并去重
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> ans;
unordered_set<int> set1(nums1.begin(),nums1.end());
// 交集匹配
for(int num : nums2){
if(set1.find(num) != set1.end()){
ans.insert(num);
}
}
return vector<int>(ans.begin(),ans.end());
}
};
350.两个数组的交集II
class Solution {
public:
// 使用关联式容器计数
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int,int> mp1;
unordered_map<int,int> mp2;
vector<int> ans;
for(int num : nums1){
mp1[num]++;
}
for(int num : nums2){
mp2[num]++;
}
// 匹配并根据最小数量输出答案
for(auto&[key,value] : mp1){
if(mp2.find(key) != mp2.end()){
int minCount = min(value,mp2[key]);
for(int i{};i < minCount;++i){
ans.emplace_back(key);
}
}
}
return ans;
}
};
202.快乐数
class Solution {
public:
// 返回数字的拆分后的平方结果
int getSum(int n){
int ans{};
while(n){
ans+=(n%10)*(n%10);
n/=10;
}
return ans;
}
// 使用关联式容器计数
bool isHappy(int n) {
unordered_set<int> unS;
while(1){
if(1 == n) return true;
int sumN = getSum(n);
if(unS.find(sumN) != unS.end()){
return false;
}
unS.insert(sumN);
n = sumN;
}
return true;
}
};
1.两数之和
class Solution {
public:
// 使用关联式容器计数
vector<int> twoSum(vector<int>& nums, int target) {
int n = nums.size();
unordered_map<int,int> mp;
for(int i{};i<n;++i){
if(mp.find(target - nums[i]) != mp.end()){
return {i,mp[target - nums[i]]};
}
mp[nums[i]] = i;
}
return {};
}
};
454.四数相加II
class Solution {
public:
// 使用关联式容器计数
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int,int> umap;
for(int a : nums1){
for(int b : nums2){
umap[a + b]++;
}
}
int ans{};
for(int a : nums3){
for(int b :nums4){
if(umap.find(0 -(a+b)) != umap.end()){
ans+= umap[0-(a+b)];
}
}
}
return ans;
}
};
15.三数之和
class Solution {
public:
// 使用关联式容器并配合双指针求解
vector<vector<int>> threeSum(vector<int>& nums) {
int n =nums.size();
int left{},right{};
vector<vector<int>> ans;
sort(nums.begin(),nums.end()); // 先排序,然后使用双指针
for(int i{};i<n;++i){
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
left = i+1;
right = n-1;
// 双指针求解
while(left < right){
int sumNum = nums[i] + nums[left] + nums[right];
if(sumNum > 0){
right--;
}else if(sumNum < 0){
left++;
}else{
ans.push_back({nums[i],nums[left],nums[right]});
while(left < right && nums[right] == nums[right-1]) right--;
while(left < right && nums[left] == nums[left+1]) left++;
right--;
left++;
}
}
}
return ans;
}
};
18.四数之和
class Solution {
public:
// 与三数之和一致:关联式容器+双指针求解,只是多嵌套了一层循环
vector<vector<int>> fourSum(vector<int>& nums, int target) {
int n = nums.size();
int left{},right{};
vector<vector<int>> ans;
sort(nums.begin(),nums.end());
for(int i{};i<n;++i){
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
for(int j = i+1;j<n;++j){
if(j > i+1 && nums[j] == nums[j-1]){
continue;
}
left = j+1;
right = n-1;
while(left <right){
if(nums[i] + nums[j] > target - (nums[left] + nums[right])){
right--;
}else if(nums[i] + nums[j] < target - (nums[left] + nums[right])){
left++;
}else{
ans.push_back({nums[i], nums[j], nums[left] ,nums[right]});
while(left < right && nums[right] == nums[right-1]) right--;
while(left < right && nums[left] == nums[left+1]) left++;
left++;
right--;
}
}
}
}
return ans;
}
};