力扣 [454、383、15、18]

这篇具有很好参考价值的文章主要介绍了力扣 [454、383、15、18]。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

454. 四数相加II

原题链接

解题思路:

哈希表:

  1. a+b+c+d=0;存在 a+b = 0 - (c + d);
  2. 那么预处理提前将 a+b 的值存入哈希表中。
  3. 然后再去搜寻 0 - (c+d) 的值,累加次数。

实现代码:

class Solution {
public:
    int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
        int cnt=0;
        unordered_map<int, int> umap;
        for (int a:A) {
            for (int b:B) {
                umap[a+b] ++;		
            }
        }
        for (int c:C) {
            for (int d:D) {
                if (umap.find(0-(c+d)) != umap.end()) {
                    cnt += umap[0 - (c+d)];
                }
            }
        }
        return cnt;
    }
};

时间复杂度:O(n^2)
空间复杂度:O(n^2),最坏情况下A和B的值各不相同,相加产生的数字个数为 n ^2。

383. 赎金信

原题链接

解题思路:

暴力法:别人的

  1. 设计两层for循环,然后外层for循环负责遍历magazine字符串。
  2. 内层循环负责在ransom字符串里面寻找对应的当前magazine[i] 字符,找到后并进行删除ransom[j],因为下次还可能再寻找,避免出现重复。
  3. 总之就是,外层循环,每次从magazine字符串里面依次取出一个字符,然后将该字符,用来去看ransom字符串里面是否有对应的字符,有的话,说明构成ransom中的一个字符,然后将ransom这个字符删除,因为已经被组建了,避免重复消耗!

实现代码:

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        
        for (int i=0; i < magazine.size(); i ++) {
            for (int j=0; j < ransomNote.size(); j ++) {
                if (magazine[i] == ransomNote[j]) {
                    ransomNote.erase(ransomNote.begin() + j);
                    break;
                }
            }
        }
        if (ransomNote.size == 0)
        return true;
        else return false;
    }
};

哈希表:别人的

  1. 题意是:用magazine里面的字符构建ransom字符串,所以说首先的一个条件就是ransom的字符串长度必须 <= magazine字符串。
  2. 然后我们可以累加 magazine字符串里面的每个字符的个数。
  3. 然后遍历ransom字符串,去消耗之前magazine里面的字符次数。如果某个字符的次数被消耗为0,则表示凑不出ransom字符串。返回false;

实现代码:

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int n1 = ransomNote.size();
        int n2 = magazine.size();

        if (n1 > n2) return false;

        int record[26] = {0};

        for (int i=0; i < n2; i ++) {
            record[magazine[i] - 'a'] ++;
        }

        for (int i=0; i < n1; i ++) {
            record[ransomNote[i] - 'a'] --;
            if (record[ransomNote[i] - 'a'] < 0) {
                return false;
            }
        }

        return true;
    }
};

15. 三数之和

原题链接

解题思路:

暴力法:自己的

  1. 三层循环;
  2. 外层循环枚举第一个数:a;
  3. 中层循环枚举第二个数:b;
  4. 内层循环枚举第三个数:c;

时间复杂度:O(n^3);
超时的!

双指针:别人的(优化)

  1. 排序,然后枚举第一个数,利用有序性,后面两个数用双指针扫描。
  2. 相比于上面的两层for循环O(n^2)扫描无疑是超时的。而用双指针扫描,则是O(n)的。
  3. 排序后,当前的序列呈非递减、允许相等的递增。
  4. 枚举第一个数nums[i],然后剪枝去重。因为有序,如果第一个数为正,三数之和不可能为0。如果nums[i] = nums[i-1],则跳过该数。
  5. 利用有序性,第二个数和第三个数双指针扫描。如果三数之和sum=0,则记录答案,左右两侧去重,若sum < 0,则l ++,r – ;继续搜索。

时间复杂度:O(n^2);

实现代码:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(), nums.end());
    
        vector<vector<int>> ans;
    
        int n = nums.size();
        
        if (n < 3) {
            return ans;
        }

        for (int i=0; i < n; i ++) {
            if (nums[i] > 0) {
                break;  //剪枝!
            }
            if (i > 0 && nums[i] == nums[i-1]) continue;    //去重!
            for (int l=i+1, r = n - 1; l < r; ) {
                int res = nums[i] + nums[l] + nums[r];
                if (res == 0) {
                    ans.push_back({nums[i], nums[l], nums[r]});
                    l ++, r --; //排除两个元素

                    while (l < r && nums[l] == nums[l-1]) l ++; //左侧去重!
                    while (r > l && nums[r] == nums[r+1]) r --; //右侧去重!
                }
                else if (res < 0) {
                    l ++;
                }
                else {
                    r --;
                }
            }
        }

        return ans;
    }
};

18. 四数之和

原题链接

解题思路:

双指针:自己的

  1. 观察数据范围;
  2. 暴力的话,则是四重循环,从左往右依次枚举。
  3. 排序:从小到大枚举!
  4. 那么我们可以采用双指针的算法。优化掉最里面的两层循环,优化为一层循环。
  5. 最终还是三层循环:外两层,枚举前两个数,内一层,采用双指针扫描后面的数。
  6. 一个指针指向左边,另一个指针指向末尾,然后分情况移动。
  7. 当四个数之和相加 == target 的时候,则将当前的四个数记录下来。然后由于要去重,我们就不断地让左指针和右指针先同步向内移动一个单位,然后先从左边元素去重,再从右边元素去重。因为排序后,相等的元素必定是会堆积到一起的!
  8. 如果四数之和大于了target的话,则说明当前过大,我们需要降低某个元素的值,那么就可以降低右边指针的,将右指针向左移动一个单位,使得第四个元素的值减小。
  9. 如果小于了target的话,则右移左指针。

实现代码:

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        int n = nums.size();
        vector<vector<int>> ans;
    
        sort(nums.begin(), nums.end());
        for (int i:nums) {
            cout << i << " ";
        }
        if (n < 4) {
            return ans;
        }

        for (int i=0; i < n - 3; i ++) {
            if (i > 0 && nums[i] == nums[i-1]) continue;
            for (int j=i+1; j < n-2; j ++) {
                if (j > i+1 && nums[j] == nums[j-1]) continue;
                int l = j + 1, r = n - 1;
                while (l < r) {
                    long res = (long)nums[i] + nums[j] + nums[l] + nums[r];

                    if (res == target) {
                        ans.push_back({nums[i], nums[j], nums[l], nums[r]});
                        l ++ , r --;

                        while (l < r && nums[l] == nums[l-1]) l ++;
                        while (l < r && nums[r] == nums[r+1]) r --;
                    }
                    else if (res > target) {
                        r --;
                    }
                    else {
                        l ++;
                    }
                }
            }
        }
        return ans;
    }
};

今日总结:

哈希表可以比对两个数据结构里面的元素。
当枚举一个序列的时候,可以使用双指针进行枚举,而双指针每次最多只能枚举两个数,若要枚举三个数,或者三个及以上的数,则需要先提前将前面的数采用嵌套for循环的方式进行枚举,然后双指针的优势是将两层for循环变为一层,即O(n^2) 变为 O(n),所以说嵌套for循环需要最后预留两个数,使用双指针进行枚举,从而将O(n ^ x) 优化为:O(n ^ x-1);文章来源地址https://www.toymoban.com/news/detail-614163.html

到了这里,关于力扣 [454、383、15、18]的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 18. 四数之和(力扣LeetCode)

    给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复): 0 = a, b, c, d n a、b、c 和 d 互不相同 nums[a] + nums[b] + nums[c] + nums[d] == target 你

    2024年02月19日
    浏览(32)
  • 【力扣】454. 四数相加 II

    【力扣】454. 四数相加 II 给你四个整数数组 nums1 、 nums2 、 nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 = i, j, k, l n nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0 示例 1: 输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2] 输出:2 解释: 两个元组如下

    2024年02月16日
    浏览(33)
  • Leetcode每日一题:18. 四数之和(2023.7.15 C++)

    目录 18. 四数之和 题目描述: 实现代码与解析: 双指针 原理思路:         给你一个由  n  个整数组成的数组  nums  ,和一个目标值  target  。请你找出并返回满足下述全部条件且 不重复 的四元组  [nums[a], nums[b], nums[c], nums[d]]  (若两个四元组元素一一对应,则认为

    2024年02月16日
    浏览(48)
  • 50倍效率!600+AI工具、3000+AI提示艺术,《AIGC万能工具包》助你职场效率起飞

    众所周知,2023年是AI元年。 以ChatGPT为例,AI能帮你 定目标、写文案,列提纲、找数据 ,甚至还能帮你做到想不到的事情…… 对不同行业的职场人士来说,它绝对是一个 省力气,省时间,能大幅度提升工作产出 的助手。 但也有人发现了,给ChatGPT不明确的指令,它并不能给

    2024年02月10日
    浏览(40)
  • LeetCode 383.赎金信

    383.赎金信 一、题目 给你两个字符串: ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以,返回 true ;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1: 示例 2: 示例 3: 提示: 1 = ransomNote.length, magazine.length = 105 ranso

    2024年02月12日
    浏览(20)
  • leetcode383. 赎金信

    题目:leetcode383. 赎金信 描述: 给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以,返回 true ;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1: 输入:ransomNote = “a”, magazine = “b” 输出:false 示例

    2024年02月13日
    浏览(28)
  • 【leetcode】383. 赎金信(easy)

    给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以,返回 true ;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。

    2024年02月13日
    浏览(22)
  • LeetCode383. Ransom Note

    Given two strings ransomNote and magazine, return true if ransomNote can be constructed by using the letters from magazine and false otherwise. Each letter in magazine can only be used once in ransomNote. Example 1: Input: ransomNote = “a”, magazine = “b” Output: false Example 2: Input: ransomNote = “aa”, magazine = “ab” Output: false Example

    2024年02月08日
    浏览(17)
  • LeetCode 454.四数相加 II

    454.四数相加 II 一、题目 给你四个整数数组 nums1 、 nums2 、 nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 = i, j, k, l n nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0 示例 1: 示例 2: 提示: n == nums1.length n == nums2.length n == nums3.length n == nums4.length 1 = n = 200

    2024年02月12日
    浏览(31)
  • LeetCode454. 4Sum II

    Given four integer arrays nums1, nums2, nums3, and nums4 all of length n, return the number of tuples (i, j, k, l) such that: 0 = i, j, k, l n nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0 Example 1: Input: nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2] Output: 2 Explanation: The two tuples are: (0, 0, 0, 1) - nums1[0] + nums2[0] + nums3[0] +

    2024年02月06日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包