力扣刷题第七天

49 阅读2分钟

454.四数相加II

int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        // 明确题目要求的是 输出有多少个满足条件的元组,所以map中 key 和 value 的选取有所不同。value不是下标,而是出现的个数
        unordered_map<int,int> mmap;
        for(int i : nums1)
        {
            for(int j : nums2)
            {
                mmap[i + j]++; // 统计前两个数组中元素之和出现的次数
            }
        }
​
        int count = 0;
​
        for(int c : nums3)
        {
            for(int d : nums4)
            {
                if(mmap.find(0 - (c + d)) != mmap.end()) // 存在
                {
                    count += mmap[0 - (c + d)];
                }
            }
        }
​
        return count;
    }

383. 赎金信

bool canConstruct(string ransomNote, string magazine) {
        int record[26] = {0};
        if(ransomNote.length() > magazine.length()) return false;
        for(char c : magazine)
        {
            record[c-'a']++;
        }
        for(char c:ransomNote)
        {
            record[c-'a']--;
            if(record[c-'a'] < 0) return false; // 再此处判断,省去了一次for循环
        }
        
        return true;
    }

15. 三数之和

vector<vector<int>> threeSum(vector<int>& nums) {
        //同一个数组中的三元组, 涉及到去重问题
        vector<vector<int>> result;
        sort(nums.begin(), nums.end());
        if(nums[0] > 0) return result;
        // 双指针,降低复杂度
        for(int i = 0; i < nums.size(); i++)
        {
​
            
            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)
                {
                    left++;
                }
                else if(nums[i] + nums[left] + nums[right] > 0)
                {
                    right--;
                }
                else{
                    result.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 result;
    }

18.四数之和

vector<vector<int>> fourSum(vector<int>& nums, int target) {
        // 核心思想等同于三数之和,都是在同一个数组中,所以都要有去重逻辑
​
        // 由于target的不确定性,所以不能利用排序后 首个元素与target的大小来去重
​
        vector<vector<int>> result;
        sort(nums.begin(),nums.end());
​
        for(int k = 0; k < nums.size(); k++)
        {
            if(k > 0 && nums[k] == nums[k-1]) continue;
​
            for(int i = k + 1; i < nums.size(); i++)
            {
                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[k] + nums[i] + nums[left] + nums[right] < target) left++;
                    else if((long)nums[k] + nums[i] + nums[left] + nums[right] > target) right--;
​
                    else {
                        result.push_back({nums[k],nums[i],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 result;
    }