今天的题目是和哈希表相关的,之后对哈希表做个总结,明天开启链表相关题目。
LeetCode 454.四数相加Ⅱ
题目链接:
解题思路:
大家上来可能想到暴力法,四个for循环来直接查找相对应的个数。但是暴力法时间复杂度太高会超出时间限制。故采取分为两两一对,之后把值存入map中,map中对应的是<a+b,出现次数>
代码:
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
map<int,int>map_1;
int n = nums1.size();
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
map_1[nums1[i]+nums2[j]]++;
}
}
int ans = 0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(map_1.count(0-nums3[i]-nums4[j])){
ans+=map_1[0-(nums3[i]+nums4[j])];
}
}
}
return ans;
}
};
LeetCode 383.救赎金
题目链接:
解题思路:
将magazine中字母存在数组类型的哈希表中,数组内对应字母出现个数。之后减去ransomNote中字母个数。判断vec中是否全部元素都大于零即可。
代码:
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
vector<int>vec(26,0);
for(char ch:magazine){
vec[ch-'a']++;
}
for(char ch:ransomNote){
vec[ch-'a']--;
}
for(int i=0;i<26;i++){
if(vec[i]<0){
return false;
}
}
return true;
}
};
LeetCode 15.三数之和
题目链接:
解题思路:
进行剪枝,减少进入循环次数,之后用set去重。
代码:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
int len = nums.size();
set<vector<int>>ans;
for(int i = 0;i<len;i++){
if(nums[i]>0){
break;
}
unordered_set<int>set;
for(int j=i+1;j<len;j++){
if (j > i + 2
&& nums[j] == nums[j-1]
&& nums[j-1] == nums[j-2]) { // 三元组元素b去重
continue;
}
int c = 0-nums[i]-nums[j];
if(set.count(c)){
ans.insert({nums[i],nums[j],c});
}
else{
set.insert(nums[j]);
}
}
}
return vector<vector<int>>(ans.begin(),ans.end());
}
};
LeetCode 18.四数之和
题目链接:
解题思路:
利用双指针,加上set去重,省去了很多判断过程
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
int len = nums.size();
set<vector<int>>set1;
for(int i=0;i<len;i++){
if(nums[i]>target && nums[i]>=0) break;
for(int j=i+1;j<len;j++){
if(nums[i]+nums[j]>target && nums[i]+nums[j]>=0) break;
int left = j+1,right = len-1;
long c = (long)target - nums[i] -nums[j];
while(left<right){
long temp = nums[left]+nums[right];
if(temp>c){
right--;
}
else if(temp<c){
left++;
}
else{
set1.insert({nums[i],nums[j],nums[left],nums[right]});
left++;
right--;
}
}
}
}
return vector<vector<int>>(set1.begin(),set1.end());
}
};
总结:
哈希表的常见哈希结构:
数组、set、map
哈希表具体使用方法见:哈希表基础