算法题丨4Sum

简介: 描述Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target?Find all unique quadruplets in the array which gives the sum of target.

描述

Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target?
Find all unique quadruplets in the array which gives the sum of target.
Note: The solution set must not contain duplicate quadruplets.

示例

Given array S = [1, 0, -1, 0, -2, 2], and target = 0.

A solution set is:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]
]

算法分析

难度:中
分析:给定整型数组和指定一个整型目标值,从整形数组中找出4个不同的元素,使得4个元素之和等于目标值,返回结果为所有满足上述条件的元素组合。
思路:思路可以参考3Sum,主要难度是由原先的找3个元素之和,变成了找4个元素之和。这种情况下,其实有点像解魔方:玩五阶魔方就是从五阶降到四阶,然后再从四阶降到三阶,最后再按照玩三阶魔方的方法解决问题。
最终的解法,其实就是在3阶解法的基础上,在外层再套一层4阶的循环,并做一些基础的判断,复杂度也是在3阶n²基础上*n=n³,当然,这种算法也可推广到n阶。

代码示例(C#)

public IList<IList<int>> FourSum(int[] nums, int target)
{
    List<IList<int>> res = new List<IList<int>>();
    if (nums.Length < 4) return res;

    //排序
    Array.Sort(nums);
    //4阶判断
    for (int i = 0; i < nums.Length - 3; i++)
    {
        //如果最近4个元素之和都大于目标值,因为数组是排序的,后续只可能更大,所以跳出循环
        if (nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) break;
        //当前元素和最后3个元素之和小于目标值即本轮最大值都小于目标值,则本轮不满足条件,跳过本轮
        if (nums[i] + nums[nums.Length - 1] + nums[nums.Length - 2] + nums[nums.Length - 3] < target)
            continue;
        //防止重复组合
        if (i > 0 && nums[i] == nums[i - 1]) continue;

        //3阶判断
        for (int j = i + 1; j < nums.Length - 2; j++)
        {
            //原理同4阶判断
            if (nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) break;
            if (nums[i] + nums[j] + nums[nums.Length - 1] + nums[nums.Length - 2] < target)
                continue;

            int lo = j + 1, hi = nums.Length - 1;
            while (lo < hi)
            {
                //已知元素 nums[i],nums[j],剩下2个元素做夹逼
                int sum = nums[i] + nums[j] + nums[lo] + nums[hi];
                if (sum == target)
                {
                    res.Add(new List<int> { nums[i], nums[j], nums[lo], nums[hi] });
                    while (lo < hi && nums[lo] == nums[lo + 1]) lo++;
                    while (lo < hi && nums[hi] == nums[hi - 1]) hi--;
                    lo++;
                    hi--;
                }
                //两边夹逼
                else if (sum < target) lo++;
                else hi--;
            }
        }
    }
    return res;
}                               

复杂度

  • 时间复杂度O (n³).
  • 空间复杂度O (1).

附录

img_8f0a90f3cbaa0e044fb8bf7b13c4317b.jpe

文章作者:原子蛋
文章出处:https://www.cnblogs.com/lizzie-xhu/
个人网站:https://www.lancel0t.cn/
个人博客:https://blog.lancel0t.cn/
微信公众号:原子蛋Live+
扫一扫左侧的二维码(或者长按识别二维码),关注本人微信公共号,获取更多资源。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

目录
相关文章
|
机器学习/深度学习 搜索推荐 算法
优秀的推荐系统架构与应用:从YouTube到Pinterest、Flink和阿里巴巴
优秀的推荐系统架构与应用:从YouTube到Pinterest、Flink和阿里巴巴
424 0
|
12月前
|
监控 安全 物联网
13位物联网卡与11位物联网卡有什么不同
物联网卡(IoT卡)的13位号码和11位号码之间存在一些关键差异。以下是针对这两者区别的详细操作步骤和解释:
|
12月前
|
Java 测试技术 开发者
初学者入门:掌握单元测试的基础与实践
【10月更文挑战第14天】单元测试是一种软件测试方法,它验证软件中的最小可测试单元——通常是单独的函数或类——是否按预期工作。单元测试的目标是确保每个模块在其自身范围内正确无误地运行。这些测试应该独立于其他模块,并且应该能够反复执行而不受外部环境的影响。
294 2
|
6月前
|
人工智能 网络协议 API
开发效率翻倍!Apipost这些协议调试秘籍,从HTTP到金融报文全搞定
Apipost是一款强大的API研发管理工具,支持多种协议与数据格式,包括HTTP(s)、WebSocket、SSE、gRPC、TCP及金融协议(如ISO 8583、FIX)。它内置国密算法库,提供HTTP文件秒传、全局参数配置等实用功能。在SSE调试中,可轻松处理AI模型流式响应;WebSocket与Socket.IO实现高效实时通信;GraphQL支持可视化Query编写;TCP模块解决金融报文编码难题;gRPC则具备服务反射与流式调试能力。Apipost不仅简化了多协议切换的复杂性,还自动生成文档,显著提升开发效率,让开发者专注于核心业务逻辑。
|
9月前
|
机器学习/深度学习 人工智能 自然语言处理
《攻克语言密码:教AI理解隐喻与象征》
在自然语言处理(NLP)领域,理解隐喻和象征是提升语言理解能力的关键。这些非字面表达承载丰富情感与文化内涵,如“时间就是金钱”或“寒梅”象征坚韧。然而,基于规则和数据驱动的NLP模型在处理这类表达时面临巨大挑战,因为它们依赖语境、文化和人类经验。未来,通过引入知识图谱、深度学习、多模态信息及上下文分析等方法,有望改善NLP对隐喻和象征的理解,推动人机交互更加自然深入。
342 15
实验:逆向分析sample_mal.exe文件
实验:逆向分析sample_mal.exe文件
|
12月前
|
存储 Docker 容器
|
Java 索引
增强for循环和一般for循环的对比使用
这篇文章对比了Java中的增强for循环(for-each循环)和传统的for循环,介绍了增强for循环的优点,如简化数组或集合的遍历、提高代码的可读性和可维护性,并指出增强for循环不适用于需要修改数组或集合元素的场景。文章还提供了增强for循环的语法格式,并展示了在实际应用中如何使用增强for循环来遍历数组和数组对象。
增强for循环和一般for循环的对比使用
|
12月前
|
安全 编译器 Go
Go runtime 调度器精讲(十):异步抢占
Go runtime 调度器精讲(十):异步抢占
|
API UED
逆向海淘代购集运系统方案:lete淘宝代购集运系统丨1688代采系统
**淘宝代购集运系统**整合多平台商品资源,提供代购、仓储、国际运输一站式服务。通过API接口实现商品实时同步,支持多种支付方式与国际物流,确保用户跨地域便利购物。系统涵盖订单管理、多语言支持、客服及营销功能,通过技术创新提升用户体验和满意度。关键点包括市场定位、支付物流体系构建、用户体验优化和API集成,助力海外用户轻松购买中国商品。