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


    LeetCode 454. 四数相加 II

    题目链接:454. 四数相加 II

    分析:
    本题比较简单,因为是无关的四个数组,所以不需要考虑去重,所以用哈希比较简单

    思路:

    1. 定义个无序map
    2. 先将nums1和nums2的和的数都存进去,并且每个数的value值都赋1
    3. 然后用个嵌套for循环去找有没有符合的数,有的话就加上对应的1,这样就出来有多少个,最后返回即可。
    class Solution {
    public:
        int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
            unordered_map<int,int> map;
            for (int a : nums1) {
                for (int b : nums2) {
                    map[a+b] ++;
                }
            }
            int count = 0;
            for (int c : nums3) {
                for (int d : nums4) {
                    if (map.find(0-c-d) != map.end()) {
                        count += map[0-c-d];
                    }
                }
            }
            return count;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述

    LeetCode 383. 赎金信

    题目链接:383. 赎金信

    分析:此题和之前做的有效字母异位词差不多,都是一样的思路

    思路:

    1. 先创建个26位的数组,
    2. 因为要判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成,所以先将magazine的所有字母的先放进去,相对位置进行++操作
    3. 然后将ransom的所有字母的再放进去,相对位置进行–操作
    4. 如果ransom可以由magazines 里面的字符构成,这时候数组里面所有位置只会有>=0的,不会又小于0的,如果有小于0的,就说明这个ransom里面出现了magazine多的字符。
    class Solution {
    public:
        bool canConstruct(string ransomNote, string magazine) {
            int fu_zhu[26] = {};
            for (int i = 0; i < magazine.length(); i++) {
                fu_zhu[magazine[i] - 'a'] ++;
            }
            for (int i = 0; i < ransomNote.length(); i++) {
                fu_zhu[ransomNote[i] - 'a'] --;
            }
            for (int i = 0; i < 26; i++) {
                if (fu_zhu[i] < 0){
                    return false;
                }
            }
            return true;
    
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    LeetCode 15. 三数之和

    题目链接:15. 三数之和

    分析:此题比较难,我知道用双指针,写了半天一直没AC,就去看卡哥的代码了,属实是妙啊

    在这里插入图片描述

    思路:

    1. 先创建个二维容器v,并且对nums排序一下
    2. 开始遍历i
    3. 进行下剪枝
    4. 去重a,注意这里使用nums[i] == nums[i-1],不然会漏掉测试情况
    5. 然后设置个左右指针,开始寻找对应的b、c的值
    6. 和大于0,右指针往左走
    7. 和小于0,左指针往右走
    8. 和正好相等,存进去
    9. 再对左右指针++和–
    class Solution {
    public:
        vector<vector<int>> threeSum(vector<int>& nums) {
            vector<vector<int>> v;
            sort(nums.begin(),nums.end());
            for(int i = 0; i < nums.size(); i++){
                if (nums[i] > 0) {
                    return v;
                }
                //去重a
                //注意这里去重的使用方法,以避免丢掉了-1,-1,2的情况
                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(vector<int>{nums[i],nums[left],nums[right]});
                        //去重 bc
                        while (left < right && nums[right] == nums[right - 1]){
                            right --;
                        }
                        while (left < right && nums[left] == nums[left + 1]) {
                            left ++;
                        }
                        left ++;
                        right --;
                    }
                }
            }
            return v;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    在这里插入图片描述

    LeetCode 18. 四数之和

    题目链接:18. 四数之和

    分析:此题有了上一题的借鉴其实也没有太难,就是多了个循环、剪枝和去重。

    思路:

    1. 先创建个二维容器v,并且对nums排序一下
    2. 开始遍历i
    3. 进行下剪枝
    4. 去重a
    5. 嵌套开始遍历j
    6. 二级剪枝
    7. 去重b
    8. 然后设置个左右指针,开始寻找对应的c、d的值
    9. 和大于0,右指针往左走
    10. 和小于0,左指针往右走
    11. 和正好相等,存进去
    12. 再对左右指针++和–
    class Solution {
    public:
        vector<vector<int>> fourSum(vector<int>& nums, int target) {
            vector<vector<int>> v;
            sort(nums.begin(),nums.end());
            for (int i = 0; i < nums.size(); i++) {
                //剪枝
                if (nums[i] > target  && nums[i] >= 0) {
                    break;
                }
                //对i去重
                if (i > 0 && nums[i] == nums[i-1]) {
                    continue;
                }
                for (int j = i+1; j < nums.size(); j++) {
                    //二级剪枝
                    if (nums[i]+nums[j] > target && nums[i]+nums[j] >= 0) {
                        break;
                    }
                    //对j进行去重
                    if (j > i+1 && nums[j] == nums[j -1]) {
                        continue;
                    }
                    int left = j + 1;
                    int right = nums.size() - 1;
                    while (left < right) {
                        if ((long)nums[i]+nums[j]+nums[left]+nums[right] > target) {
                            right --;
                        }
                        else if ((long)nums[i]+nums[j]+nums[left]+nums[right] < target) {
                            left ++;
                        }
                        else{
                            v.push_back(vector<int>{nums[i],nums[j],nums[left],nums[right]});
                            //去重cd
                            while (left < right && nums[right] == nums[right - 1]){
                                right--;
                            }
                            while (left < right && nums[left] == nums[left + 1]){
                                left++;
    
                            }
                            left ++;
                            right --;
                        }
                    }
                }
            }
            return v;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    在这里插入图片描述

  • 相关阅读:
    记一次有意思的 SQL 实现 → 分组后取每组的第一条记录
    Django JWT验证
    学习Makefile例子
    为什么大家都开始做游戏化产品?
    Java-集合类
    vue3+vite 中使用百度地图【两种方式】
    软件工程第四周
    Sentinel源码剖析之核心组件作用和介绍
    Java乐观锁的实现
    华秋DFM从2.1.6升级到3.x版本出现的问题
  • 原文地址:https://blog.csdn.net/weixin_41603934/article/details/127992380