代码随想录算法训练营day7 || 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

问题1:454. 四数相加 II - 力扣(LeetCode)

思路:该题用暴力法显然复杂度太高,因此需要采用map,先记录两个数的和出现的次数,键为两个数的和,然后再用map去寻找,若发现了则加上该位置的值。代码如下:

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int,int> countab;
        for(int a:nums1){
            for(int b:nums2) ++countab[a+b];
        }
        int result=0;
        for(int a:nums3){
            for(int b:nums4) {
                if(countab.find(-a-b)!=countab.end()){
                    result+=countab[-(a+b)];
                }
            }
        }
        return result;

    }
};

问题2:383. 赎金信 - 力扣(LeetCode)

思路:先定义一个数组,长度为26,用来记录字符出现的次数,先遍历长度大的字符串,并在数组中相应的位置做自加,接着再遍历长度小的字符串,在相应位置做自减,若有发现数组中有小于0的存在,则返回false,代码如下:

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

问题3:15. 三数之和 - 力扣(LeetCode)

思路:双指针法。首先对数组进行排序,在对数组进行遍历时,定义一个right和left进行求和并与目标值比较,若大于则自减,小于则左自加;同时在各个部分做好去重语句,代码如下:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result; 
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size();i++){
            if(nums[i]>0) return result;
            if(i>0 && nums[i]==nums[i-1]){
                continue;
            }
            int left=i+1;
            int right=nums.size()-1;
            while(right>left){
                if(nums[i]+nums[left]+nums[right]>0) right--;
                else if(nums[i]+nums[left]+nums[right]<0) left++;
                else{
                    result.push_back(vector<int>{nums[i],nums[left],nums[right]});
                    while(right>left && nums[right]==nums[right-1]) right--;
                    while(right>left && nums[left]==nums[left+1]) left++;
                    left++;
                    right--;
                }
            }

        }
        return result;
    }
};

问题4:18. 四数之和 - 力扣(LeetCode)

思路:在三数之和中多了一个循环和一些去重语句,代码如下:

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

猜你喜欢

转载自blog.csdn.net/weixin_56969073/article/details/132416979