代码随想录训练营第六天 454四数相加II 383赎金信 15三数之和 18四数之和

第一题:

原题链接:454. 四数相加 II - 力扣(LeetCode)

思路:

将四个数组分成两两 两个组合,先对前面两个数组进行操作

定义unordered_map<int, int> map,将第一个和第二个数组中的元素相加并填入map中,记录相加之后元素的值对应出现的个数。

然后再对第三和第四个数组进行操作

定义一个值target为第三和第四数组中元素相加后取反,在map中查找该元素是否存在,若存在结果+=map[target]。因为存在证明在第一个和第二个数组中存在对应元素出现的个数。

代码如下:

cpp 复制代码
class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int, int> map;
        for(auto a : nums1){
            for(auto b : nums2){
                map[a + b] += 1;
            }
        }
        int res = 0;
        for(auto c : nums3){
            for(auto d : nums4){
                int target = -(c + d);
                if(map.find(target) != map.end()){
                    res += map[target];
                }
            }
        }
        return res;
    }
};

第二题:

原题链接:383. 赎金信 - 力扣(LeetCode)

思路:

定义unordered_map<char, int> map,遍历第一个字符串,记录每个字符出现的次数,

遍历第二个字符串,当出现和map中存在的字符,记录的次数减一,

最后遍历整个map,观察每个pair中的第二值是否>0,是则说明无法构成,返回false,反之为true;

代码如下:

cpp 复制代码
class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        unordered_map<char, int> map;
        for(int i = 0; i < ransomNote.size(); i++){
            map[ransomNote[i]] += 1;
        }
        for(int i = 0; i < magazine.size(); i++){
            if(map.find(magazine[i]) != map.end()){
                map[magazine[i]] -= 1;
            }
        }
        for(auto x : map){
            if(x.second > 0){
                return false;
            }
        }
        return true;
    }
};

第三题:

原题链接:15. 三数之和 - 力扣(LeetCode)

思路:

此题用双指针更好做一些。

首先对数组进行排序,这点很关键,可以剪枝。应为题目要求不能包含重复的三元组,因此不能出现重复的元素。当我们排完序之后,想同的元素就紧挨在一起便于我们操作

遍历整个数组,然后定义两根指针分别指向当前遍历的位置加一和数组末尾的位置。先判断我们当前遍历的位置的值是否大于0,如果大于0直接返回res,因为排过序后当前值大于0后面的值也大于0。剪枝操作:当前元素和前一个元素的值相同,可以直接跳过。

接在在right > left的循环里判断三数之和是否大于0,大于0right--,如果小于0left++,如果等于0,将这三个值插入res中,然后判断left的值和left+1的值是否相同,相同也要跳过。right同理。

最后返回res。

代码如下:

cpp 复制代码
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());
        for(int i = 0; i < nums.size(); i++){
            if(nums[i] > 0) return res;
            if(i > 0 && nums[i] == nums[i - 1]) continue;
            int left = i + 1, 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{
                    res.push_back({nums[i], nums[left], nums[right]});
                    while(right > left && nums[right - 1] == nums[right]) right--;
                    while(right > left && nums[left + 1] == nums[left]) left++;
                    left++;
                    right--;
                }
            }
        }
        return res;
    }
};

第四题

原题链接:18. 四数之和 - 力扣(LeetCode)

思路:

和上一题相似,就是在套一层循环.

代码如下:

cpp 复制代码
class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());
        for(int k = 0; k < nums.size(); k++){
            if(nums[k] > target && nums[k] >= 0) return res;
            if(k > 0 && nums[k] == nums[k - 1]) continue;
            for(int i = k + 1; i < nums.size(); i++){
                if(nums[i] + nums[k]> target && nums[k] >= 0){
                    return res;
                }
                if(i > k + 1 && nums[i] == nums[i - 1]) continue;
                int left = i + 1, right = nums.size() - 1;
                while(right > left){
                    if((long)nums[i] + nums[k] + nums[left] + nums[right] < target){
                        left++;
                    }
                    else if((long)nums[i] + nums[k] + nums[left] + nums[right] > target){
                        right--;
                    }else{
                        res.push_back({nums[i], nums[k], nums[left], nums[right]});
                        while(right > left && nums[right - 1] == nums[right]) right--;
                        while(right > left && nums[left + 1] == nums[left]) left++;
                        right--;
                        left++;
                    }
                }
            }
        }
        return res;
    }
};
相关推荐
pianmian11 小时前
python数据结构基础(7)
数据结构·算法
好奇龙猫3 小时前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
sp_fyf_20244 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
香菜大丸4 小时前
链表的归并排序
数据结构·算法·链表
jrrz08284 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
oliveira-time5 小时前
golang学习2
算法
南宫生5 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法
懒惰才能让科技进步6 小时前
从零学习大模型(十二)-----基于梯度的重要性剪枝(Gradient-based Pruning)
人工智能·深度学习·学习·算法·chatgpt·transformer·剪枝
Ni-Guvara6 小时前
函数对象笔记
c++·算法
泉崎7 小时前
11.7比赛总结
数据结构·算法