代码随想录算法训练营第七天|454.两数相加、383.赎金信、15.三数之和、18、四数之和

哈希表

454.两数相加

unordered_map

迭代器

begin,cbegin (C++11)返回指向起始的迭代器(公开成员函数)

end,cend (C++11)返回指向末尾的迭代器(公开成员函数)

容量

empty (C++11)检查容器是否为空(公开成员函数)

size (C++11)返回容纳的元素数(公开成员函数)

修改器

clear (C++11)清除内容(公开成员函数)

insert (C++11) 插入元素或结点 (C++17 起)(公开成员函数)

erase (C++11)擦除元素(公开成员函数)

查找

find (C++11)寻找带有特定键的元素(公开成员函数)

contains (C++20)检查容器是否含有带特定键的元素(公开成员函数)

 class Solution {
 public:
     int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
         //将nums1,nums2的和存入哈希表中,之后遍历nums3,nums4判断是否存在-nums3-nums4
         //因为存在重复的和,且需要记录重复的次数,因此使用unordered_map,查找复杂度为O(1)
         std::unordered_map<int,int> map;
         for(int i = 0;i < nums1.size();i++){
             for(int j = 0;j < nums2.size();j++){
                 auto search = map.find(nums1[i]+nums2[j]);//O(1)
                 
                 if(search == map.end())map.insert({nums1[i]+nums2[j],1});
                 else ++search->second;
             }
         }
         int count = 0;
         for(int i = 0;i < nums3.size();i++){
             for(int j = 0;j < nums4.size();j++){
                 auto search = map.find(0-nums3[i]-nums4[j]);
                 if(search != map.end())count+= search->second;
             }
         }
         return count;
     }
 };//O(n^2)

383.赎金信

 class Solution {
 public:
     bool canConstruct(string ransomNote, string magazine) {
         int nums[26] = {0};//一共只有26个元素,因此可以使用数组实现哈希表,
                            //存储magazine中字母出现的次数
         for(int i = 0;i < magazine.size();i++){
             nums[magazine[i]-'a']++;
         }
 ​
         for(int i = 0;i < ransomNote.size();i++){
             if(--nums[ransomNote[i]-'a'] < 0)return false;
         }
         return true;
     }
 };//O(n)

15.三数之和

暴力解

```C++
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<vector<int>> ans;
        //排序之后,三元组每个位置的元素和上一次枚举的元素不同时,才枚举
        for(int i = 0;i < nums.size();i++){
            if(nums[i] > 0)break;
            if(i > 0 && nums[i] == nums[i-1])continue;//a去重
            for(int j = i+1;j < nums.size();j++){
                if(j > i+1 &&nums[j] == nums[j-1])continue;//b去重
                for(int k = j+1;k < nums.size();k++){
                    if(k > j+1 && nums[k] == nums[k-1])continue;//c去重
                    if(nums[i]+nums[j]+nums[k] ==0)
                    ans.push_back({nums[i],nums[j],nums[k]});
                }
            }
        }    
        return ans;
    }
};//O(n^3)
```

双指针:将两层for循环将为一层for

当j向后移动一个位置的时候,k向前移动若干位置

```C++
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<vector<int>> ans;
        int len = nums.size();
        //排序之后,三元组每个位置的元素和上一次枚举的元素不同时,才枚举
        for(int i = 0;i < nums.size();i++){
            if(nums[i] > 0)break;
            if(i > 0 && nums[i] == nums[i-1])continue;//a去重
            int k = len-1;
            for(int j = i+1;j < nums.size();j++){
                if(j > i+1 && nums[j] == nums[j-1])continue;//b去重
                while(j < k&&nums[i]+nums[j]+nums[k] > 0)k--;
                //c的去重随着b的去重,一同被去重
                if(j == k)break;
                if(nums[i]+nums[j]+nums[k] == 0)
                    ans.push_back({nums[i],nums[j],nums[k]});
            }
        }    
        return ans;
    }
};//O(n^2)
```

18、四数之和

暴力解

```C++
class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        sort(nums.begin(),nums.end());
        vector<vector<int>> ans;
        for(int i = 0;i < nums.size();i++){
            if(i > 0 && nums[i] == nums[i-1])continue;
            for(int j = i+1;j < nums.size();j++){
                if(j > i+1 && nums[j] == nums[j-1])continue;
                for(int k = j+1;k < nums.size();k++){
                    if(k > j+1 && nums[k] == nums[k-1])continue;
                    for(int l = k+1;l < nums.size();l++){
                        if(l > k+1 && nums[l] == nums[l-1])continue;
                        long sum = (long)nums[i]+nums[j]+nums[k]+nums[l];
                        if(sum == target)
                        ans.push_back({nums[i],nums[j],nums[k],nums[l]});
                    }       
                }
            }
        }
        return ans;
    }
};//O(n^4)

使用双指针降低复杂度

```C++
class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        sort(nums.begin(),nums.end());
        vector<vector<int>> ans;
        for(int i = 0;i < nums.size();i++){
            if(i > 0 && nums[i] == nums[i-1])continue;//去重
            for(int j = i+1;j < nums.size();j++){
                if(j > i+1 && nums[j] == nums[j-1])continue;//

                int l = nums.size() - 1;
                for(int k = j+1;k < nums.size();k++){//双指针代替两重循环
                    if(k > j+1 && nums[k] == nums[k-1])continue;//
                    while(k < l && (long)nums[i]+nums[j]+nums[k]+nums[l] > target)l--;
                    if(l == k)break;
                    if((long)nums[i]+nums[j]+nums[k]+nums[l] == target)
                    ans.push_back({nums[i],nums[j],nums[k],nums[l]});
                        
                }
            }
        }
        return ans;
    }
};//O(n^3)

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值