代码随想录day7 LeetCode 454. 四数相加 II 383. 赎金信 15.三数之和 18四数之和

454. 四数相加 II

https://leetcode.cn/problems/4sum-ii/

采用哈希表法,能比暴力法减少时间复杂度,先用两个数之和做出哈希表,再用剩下两数之和寻找哈希表中的数

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int,int>hash;
        for(int i=0;i<nums1.size();i++){
            for(int j=0;j<nums2.size();j++){
                int sum=nums1[i]+nums2[j];
                 if(hash.find(sum)!=hash.end())hash[sum]++;
                else hash[sum]=1;
            }
        }
        int count=0;
        for(int i=0;i<nums3.size();i++){
            for(int j=0;j<nums4.size();j++){
                if(hash.find(-1*(nums3[i]+nums4[j]))!=hash.end()){
                    count+=hash.find(-1*(nums3[i]+nums4[j]))->second;
                }
            }
        }
        return count;
    }
};

383.赎金信

https://leetcode.cn/problems/ransom-note/

双指针的拓展

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
            int hash[26]={0};
            for(int i=0;i<magazine.size();i++){
                hash[magazine[i]-'a']++;
            }
            for(int i=0;i<ransomNote.size();i++){
                hash[ransomNote[i]-'a']--;
            }
            for(int i=0;i<26;i++){
                if(hash[i]<0)return 0;
            }
            return 1;
    }
};

15.三数之和

https://leetcode.cn/problems/3sum/

双指针的变形“三指针法”

此题注意去重的细节,三个数都需要去重否则将考虑不全面,如(0,0,0,0)等等

class Solution {
public:
    vector<vector<int>> threeSum(vector<int> &nums) {
        unordered_map<int,int>hash;
        sort(nums.begin(),nums.end());
        vector<int>v;

        vector<vector<int>>v1;

        int j=0;
        for(int i=0;i<nums.size();i++){
            if(nums[i]>0)return v1;
            if(i>0&&nums[i]==nums[i-1])continue;
            int left=i+1;
            int right=nums.size()-1;
            while(left<right) {

                if (nums[i] + nums[left] + nums[right] > 0)right--;
                else if (nums[i] + nums[left] + nums[right] < 0)left++;
                else {
                    v.push_back(nums[i]),v.push_back(nums[left]),v.push_back(nums[right]),v1.push_back(v),v.clear();
                    //把无效移动给剔除
                    while(left<right&&nums[right]==nums[right-1])right--;
                    while(left<right&&nums[left]==nums[left+1])left++;
                    left++;
                    right--;
                }
            }
        }
        return v1;
    }
};

 4.四数之和

https://leetcode.cn/problems/4sum/

三数之和的拓展,运用”四指针法”,再设一指针k,同时注意四个去重

class Solution {
public:
    vector <vector<int>> fourSum(vector<int> &nums, int target) {
        vector<vector<int>> result;
        sort(nums.begin(), nums.end());
        for (int k = 0; k < nums.size(); k++) {
            if (nums[k] >= 0 && nums[k] > target) {
                break;
            }
            if(k>0&&nums[k]==nums[k-1])continue;//注意不能用while
            for(int i=k+1;i<nums.size();i++){
                if((nums[i]+nums[k])>=0&&nums[i]+nums[k]>target)break;
                if(i>k+1&&nums[i]==nums[i-1])continue;
                int left=i+1;int right=nums.size()-1;
                while(left<right){
                    if((long)nums[left]+nums[right]+nums[k]+nums[i]<target)left++;
                    else if((long)nums[left]+nums[right]+nums[k]+nums[i]>target)right--;//注意数据会溢出
                    else {
                        result.push_back(vector<int>{nums[k],nums[i],nums[left],nums[right]});
                        while(left<right&&nums[left]==nums[left+1]){
                            left++;
                        }
                        while(left<right&&nums[right]==nums[right-1]){
                           right--;
                        }
                        left++;
                        right--;
                    }
                }
            }
        }
        return result;
    }
};

 

posted @ 2023-01-04 12:02  芝士可乐  阅读(21)  评论(0)    收藏  举报