【代码随想录 | Leetcode | 第十天】哈希表 | 三数之和 | 四数之和

这篇具有很好参考价值的文章主要介绍了【代码随想录 | Leetcode | 第十天】哈希表 | 三数之和 | 四数之和。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

欢迎来到小K的Leetcode|代码随想录|专题化专栏,今天将为大家带来哈希法~三数之和 | 四数之和的分享


15. 三数之和

✨题目链接点这里
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足i != j、i != k 且 j != k,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。

示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

提示:
3 <= nums.length <= 3000
-105 <= nums[i] <= 105

「方法一」:哈希法,直接两层for循环确定第一个和第二个数,然后在哈希表中查找最后一个数,思路没有问题,但是实现起来很困难,就是去重的问题和时间复杂度的问题,去重主要是第二个数的去重【因为数组已经排序,如果连续的三个数字相同,那么它们组成的三元组只能是一种情况,不需要重复计算】,第二个就是时间复杂度的问题,这个真不好解决,只能注意去重的细节,因为本身就有两个for循环,在加上erase和insert操作~我这里是险过

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) break;
            if (i > 0 && nums[i] == nums[i-1]) continue;
            unordered_set<int> set;
            for (int j = i + 1; j < nums.size(); j++) {
                if (j > i + 2 && nums[j] == nums[j-1] && nums[j-1] == nums[j-2]) continue;
                int c = - (nums[i] + nums[j]);
                if (set.find(c) != set.end()) {
                    result.push_back({nums[i] , nums[j] , c});
                    set.erase(c);
                }
                else set.insert(nums[j]);
            }
        }
        return result;
    }
};

【代码随想录 | Leetcode | 第十天】哈希表 | 三数之和 | 四数之和,# Leetcode | 代码随想录 | 专题化,leetcode,散列表,算法

「方法二」:双指针法
【代码随想录 | Leetcode | 第十天】哈希表 | 三数之和 | 四数之和,# Leetcode | 代码随想录 | 专题化,leetcode,散列表,算法

拿这个nums数组来举例,首先将数组排序,然后有一层for循环,i从下标0的地方开始,同时定一个下标left 定义在i+1的位置上,定义下标right 在数组结尾的位置上。

依然还是在数组中找到 abc 使得a + b +c =0,我们这里相当于 a = nums[i],b = nums[left],c = nums[right]。

接下来如何移动left 和right呢, 如果nums[i] + nums[left] + nums[right] > 0 就说明 此时三数之和大了,因为数组是排序后了,所以right下标就应该向左移动,这样才能让三数之和小一些。

如果 nums[i] + nums[left] + nums[right] < 0 说明 此时 三数之和小了,left 就向右移动,才能让三数之和大一些,直到left与right相遇为止。

Tips:这里说答案中不可以包含重复的三元组,并不是说三元组中不能有重复元素,但是重复元素不能是同一位置所以这里去重使用的是nums[i] == nums[i-1],而不是nums[i] == nums[i+1]

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 (left < right) {
                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 (left < right && nums[right] == nums[right-1]) right--;
                    while (left < right && nums[left] == nums[left+1]) left++;
                    left++ , right--;
                }
            }
        }
        return result;
    }
};

【代码随想录 | Leetcode | 第十天】哈希表 | 三数之和 | 四数之和,# Leetcode | 代码随想录 | 专题化,leetcode,散列表,算法

18. 四数之和

✨题目链接点这里
给你一个由 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你可以按 任意顺序 返回答案 。

示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]

示例 2:
输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]

提示:
1 <= nums.length <= 200
-109 <= nums[i] <= 109
-109 <= target <= 109

使用双指针,和上一题思路一样,只是多加了一层for循环

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

【代码随想录 | Leetcode | 第十天】哈希表 | 三数之和 | 四数之和,# Leetcode | 代码随想录 | 专题化,leetcode,散列表,算法

总结

要恰当使用哈希法,并根据实际情况选择合适的结构(数组,set,map)文章来源地址https://www.toymoban.com/news/detail-614468.html

到了这里,关于【代码随想录 | Leetcode | 第十天】哈希表 | 三数之和 | 四数之和的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 代码随想录第6天| 哈希表理论基础 ,LeetCode242.有效的字母异位词,LeetCode349. 两个数组的交集,LeetCode202. 快乐数,LeetCode1. 两数之和

    哈希表(散列表)理论基础 : 哈希表是根据关键码的值而直接进行访问的数据结构。 直白来讲其实数组就是一张哈希表。   什么时候想到用哈希法, 当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法 。 当我们遇到了要快速判断一个元素是否出现集

    2024年02月10日
    浏览(61)
  • 代码随想录 -- 哈希表--两数之和

    力扣hot1:两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。 示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] +

    2024年02月09日
    浏览(36)
  • 【代码随想录06】454. 四数相加 II 383. 赎金信 15. 三数之和 18. 四数之和

    题目描述 给你四个整数数组 nums1 、 nums2 、 nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 = i, j, k, l n nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0 做题思路 本题可以使用哈希表, key 为 nums1[i] + nums2[j] 的和, value 为其出现的次数。然后再遍历 nums3 和

    2024年01月16日
    浏览(43)
  • 我在代码随想录|写代码Day7之454.四数相加II ,​ 383. 赎金信​,​ 15. 三数之和​

    题目  解题思路 四个数字相加的和为0,我们要选俩数组,让他们的笛卡尔积储存在哈希表中,然后我们要找的是这俩数和的相反数,然后就是将后面俩数组相加在后面的数组和中找相反数.   解题思路 题目意思是让在字符串1中找到字母组成字符串2所以找字符串1的数量.所以可以用

    2024年01月20日
    浏览(39)
  • 【代码随想录-哈希表】有效的字母异位词

    💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老 导航 檀越剑指大厂系列:全面总

    2024年02月21日
    浏览(49)
  • Day7代码随想录(1刷) 哈希表

    目录 454. 四数相加 II  383. 赎金信 15. 三数之和  18. 四数之和   给你四个整数数组  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.l

    2024年03月25日
    浏览(44)
  • 代码随想录二刷-哈希表-几数之和 (JS)

    题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。 如果这个过程 结果为 1,那么这个数就是快乐数。 如果

    2023年04月18日
    浏览(35)
  • 代码随想录Leetcode70. 爬楼梯

            空间复杂度为O(N),如果想要优化空间复杂度,则只用三个变量进行状态转移也可以,参考 代码随想录 Leetcode509. 斐波那契数-CSDN博客

    2024年02月19日
    浏览(68)
  • 代码随想录Leetcode 343. 整数拆分

            dp[i]表示i所能拆分的最大乘积,则dp[i] 与dp[i - 1]的递推公式是:                 max( 1~n * dp[n ~ 1])

    2024年02月21日
    浏览(74)
  • 代码随想录 Leetcode18. 四数之和

            不行了,今天做了太多n数之和要吐了,太恶心了,一堆剪枝,去重太恶心人了。最后还是照着卡哥的改

    2024年01月17日
    浏览(91)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包