C语言编程--15.四数之和

题目:

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

  1. 0 <= a, b, c, d < n
  2. a、b、c 和 d 互不相同
  3. 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

代码:

#include <stdlib.h>// 比较函数,用于 qsort 对数组进行排序
// pa 和 pb 是指向要比较元素的指针
// 返回值为 1 表示 a > b,返回 -1 表示 a < b
int cmp(const void* pa, const void* pb)
{int a = *(int*)pa;  // 将 pa 指针指向的元素转换为 int 类型并赋值给 aint b = *(int*)pb;  // 将 pb 指针指向的元素转换为 int 类型并赋值给 breturn a > b ? 1 : -1;  // 如果 a 大于 b 返回 1,否则返回 -1
}// 四数之和函数,用于找出数组中所有不重复的四元组,使得它们的和等于目标值
// nums 是输入的整数数组
// numsSize 是数组的长度
// target 是目标和
// returnSize 是返回的四元组的数量
// returnColumnSizes 是每个四元组的长度(固定为 4)
int** fourSum(int* nums, int numsSize, int target, int* returnSize, int** returnColumnSizes) {qsort(nums, numsSize, sizeof(int), cmp);  // 对数组进行排序,方便后续去重和双指针操作int base = 100;  // 初始分配的结果数组的容量int **result = (int**)malloc(sizeof(int*) * base);  // 动态分配存储四元组的二维数组*returnColumnSizes = (int*)malloc(sizeof(int) * base);  // 动态分配存储每个四元组长度的数组*returnSize = 0;  // 初始化返回的四元组数量为 0// 如果数组长度小于 4,直接返回空结果if (numsSize < 4) {return result;}// 外层循环,固定第一个数for(int i = 0; i < numsSize - 3; i++) {// 跳过重复的第一个数,避免结果中出现重复的四元组if (i > 0 && nums[i] == nums[i - 1])continue;// 第二层循环,固定第二个数for(int j = i + 1; j < numsSize - 2; j++) {// 跳过重复的第二个数,避免结果中出现重复的四元组if (j > i + 1 && nums[j] == nums[j - 1])continue;int l = j + 1;  // 左指针,指向第二个数的下一个位置int r = numsSize - 1;  // 右指针,指向数组的最后一个位置// 双指针法,在剩余的元素中寻找满足条件的第三个数和第四个数while (l < r) {// 计算四个数的和,使用 long long 类型避免整数溢出long long sum = (long long)nums[i] + (long long)nums[j] + (long long)nums[l] + (long long)nums[r];long long temp = sum - target;  // 计算当前和与目标值的差值// 如果差值为 0,说明找到了一个满足条件的四元组if (temp == 0) {result[*returnSize] = (int*)malloc(sizeof(int) * 4);  // 为新的四元组分配内存(*returnColumnSizes)[*returnSize] = 4;  // 设置该四元组的长度为 4result[*returnSize][0] = nums[i];  // 存储第一个数result[*returnSize][1] = nums[j];  // 存储第二个数result[*returnSize][2] = nums[l];  // 存储第三个数result[*returnSize][3] = nums[r];  // 存储第四个数(*returnSize)++;  // 四元组数量加 1// 如果结果数组的容量不够,扩大容量if (*returnSize == base) {base *= 2;  // 容量翻倍result = (int**)realloc(result, sizeof(int*) * base);  // 重新分配结果数组的内存*returnColumnSizes = (int*)realloc(*returnColumnSizes, sizeof(int) * base);  // 重新分配每个四元组长度数组的内存}int a = nums[l];  // 记录当前左指针指向的数int b = nums[r];  // 记录当前右指针指向的数// 跳过重复的第三个数while (nums[l] == a && l < r)l++;// 跳过重复的第四个数while (nums[r] == b && l < r)r--;} // 如果当前和大于目标值,右指针左移else if (temp > 0) {r--;} // 如果当前和小于目标值,左指针右移else {l++;}   }}}return result;  // 返回存储所有满足条件四元组的二维数组
}

代码分析:

优点

  1. 排序和双指针法:通过对数组进行排序,然后使用双指针法,将原本的暴力枚举 O(n4)的时间复杂度降低到了O(n3),提高了算法的效率。
  2. 去重处理:在每一层循环中都进行了去重处理,避免了结果中出现重复的四元组,保证了结果的正确性。
  3. 动态内存分配:使用 malloc 和 realloc 动态分配内存,根据实际结果的数量调整内存大小,避免了内存的浪费。
  4. 处理整数溢出:在计算四个数的和时,使用 long long 类型,避免了整数溢出的问题,提高了代码的健壮性。

缺点

  1. 时间复杂度较高:虽然使用了双指针法将时间复杂度从 O(n4)的时间复杂度降低到了O(n3),但对于大规模数据,仍然可能会超时。
  2. 内存管理复杂:使用了动态内存分配,需要手动管理内存,容易出现内存泄漏的问题。在使用完返回的结果数组后,需要调用者手动释放内存。
  3. 提前剪枝不足:代码中虽然有一些基本的逻辑,但没有充分利用排序后的数组特性进行更有效的提前剪枝,例如可以在某些情况下提前终止循环,减少不必要的计算。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/78047.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025.04.23【探索工具】| STEMNET:高效数据排序与可视化的新利器

文章目录 1. STEMNET工具简介2. STEMNET的安装方法3. STEMNET常用命令 1. STEMNET工具简介 在生物信息学领域&#xff0c;分析和处理大规模数据集是研究者们面临的日常挑战。STEMNET工具应运而生&#xff0c;旨在提供一个强大的平台&#xff0c;用于探索和分析单细胞RNA测序&a…

Day-3 应急响应实战

应急响应实战一&#xff1a;Web入侵与数据泄露分析 1. Web入侵核心原理 ​​漏洞利用路径​​ 未授权访问&#xff1a;弱口令&#xff08;如空密码/默认口令&#xff09;、目录遍历漏洞代码注入攻击&#xff1a;JSP/ASP木马、PHP一句话木马&#xff08;利用eval($_POST[cmd])&…

两段文本比对,高亮出差异部分

用法一:computed <div class"card" v-if"showFlag"><div class"info">*红色背景为已删除内容&#xff0c;绿色背景为新增内容</div><el-form-item label"与上季度比对&#xff1a;"><div class"comp…

Python中的 for 与 迭代器

文章目录 一、for 循环的底层机制示例&#xff1a;手动模拟 for 循环 二、可迭代对象 vs 迭代器关键区别&#xff1a; 三、for 循环的典型应用场景1. 遍历序列类型2. 遍历字典3. 结合 range() 生成数字序列4. 遍历文件内容 四、迭代器的自定义实现示例&#xff1a;生成斐波那契…

Pytest教程:为什么Pytest要用插件模式?

目录 一、历史背景:测试框架的局限性与Pytest的设计哲学 1.1 早期测试框架的困境 1.2 Pytest的模块化设计 二、横向对比:插件机制如何让Pytest脱颖而出 2.1 与Unittest/Nose的对比 2.2 插件模式的架构优势 三、插件模式的核心优势解析 3.1 可扩展性:从单元测试到全链…

【深度】如何通过MCP实现多智能体之间的协同

来源&#xff1a;腾讯技术工程、infoQ、原力注入 自 OpenAI 于 2023 年发布函数调用功能以来&#xff0c;我一直在思考如何构建一个开放的智能体与工具使用生态系统。随着基础模型愈发智能化&#xff0c;智能体与外部工具、数据和 API 的交互能力却日益碎片化&#xff1a;开发…

NVIDIA自动驾驶安全与技术读后感

ll在阅读了 NVIDIA 自动驾驶安全报告后&#xff0c;我对该公司致力于推进自动驾驶汽车&#xff08;AV&#xff09;技术、同时优先考虑安全和标准化的承诺印象深刻。它揭示了 NVIDIA 在功能安全、法规合规性以及与全球标准组织合作方面的严谨态度。    报告中最引人注目的部分…

关于nginx,负载均衡是什么?它能给我们的业务带来什么?怎么去配置它?

User 关于nginx&#xff0c;我还想知道&#xff0c;负载均衡是什么&#xff1f;它能为我的业务带来什么&#xff1f;怎么去配置它&#xff1f; Assistant 负载均衡是 Nginx 另一个非常强大的功能&#xff0c;也是构建高可用、高性能应用的关键技术之一。我们来详细了解一下。 …

前端如何优雅地对接后端

作为一名前端开发者&#xff0c;与后端对接是我们日常工作中不可避免的一部分。从API设计的理解到错误处理的优雅实现&#xff0c;前端需要的不只是调用接口的代码&#xff0c;更是一种协作的艺术。本文将从Vue 3项目出发&#xff0c;分享如何与后端高效协作&#xff0c;减少联…

PYTHON用几何布朗运动模型和蒙特卡罗MONTE CARLO随机过程模拟股票价格可视化分析耐克NKE股价时间序列数据

原文链接&#xff1a;http://tecdat.cn/?p27099 金融资产/证券已使用多种技术进行建模。该项目的主要目标是使用几何布朗运动模型和蒙特卡罗模拟来模拟股票价格。该模型基于受乘性噪声影响的随机&#xff08;与确定性相反&#xff09;变量&#xff08;点击文末“阅读原文”获取…

头歌之动手学人工智能-机器学习 --- PCA

目录 第1关&#xff1a;维数灾难与降维 第2关&#xff1a;PCA算法流程 任务描述 编程要求 测试说明 第3关&#xff1a;sklearn中的PCA 任务描述 编程要求 测试说明 第1关&#xff1a;维数灾难与降维 第2关&#xff1a;PCA算法流程 任务描述 本关任务&#xff1a;补充…

IOMUXC_SetPinMux的0,1参数解释

IOMUXC_SetPinMux(IOMUXC_ENET1_RX_DATA0_FLEXCAN1_TX, 0); 这里的第二个参数 0 实际上传递给了 inputOnfield&#xff0c;它控制的是 SION&#xff08;Software Input On&#xff09;位。 当 inputOnfield 为 0 时&#xff0c;SION 关闭&#xff0c;此时引脚的输入/输出方向由…

express响应设置 以及redirect,download,json.sendFdile

Express 中常用响应方法 的整理&#xff0c;包括设置响应头、重定向、下载、发送 JSON、发送文件等&#x1f447; &#x1f4e4; 一、设置响应头与状态码 设置状态码 res.status(404).send(Not Found);设置响应头 res.set(Content-Type, text/plain); // 设置内容类型 res.s…

深度学习-数值稳定性和模型初始化

到目前为止&#xff0c;我们实现的每个模型都是根据某个预先制定的分布来初始化模型的参数&#xff0c;有人会认为初始化方案时理所当然的&#xff0c;忽略了如何做出这些选择的细节&#xff0c;甚至有人可能会觉得&#xff0c;初始化方案的选择并不是特别重要&#xff0c;实际…

SFINAE(Substitution Failure Is Not An Error)

C 中的 SFINAE&#xff08;替换失败并非错误&#xff09; SFINAE&#xff08;Substitution Failure Is Not An Error&#xff09;是 C 模板元编程的核心机制之一&#xff0c;允许在编译时根据类型特性选择不同的模板实现。以下通过代码示例和底层原理&#xff0c;逐步解析 SFI…

【Python笔记 04】输入函数、转义字符

一、Input 输入函数 prompt是提示&#xff0c;会在控制台显示&#xff0c;用作提示函数。 name input("请输入您的姓名&#xff1a;") print (name)提示你输入任意信息&#xff1a; 输入input test后回车&#xff0c;他输出input test 二、常用的转义字符 只讲…

什么是量子计算?它能做什么?

抛一枚硬币。要么正面朝上&#xff0c;要么反面朝上&#xff0c;对吧&#xff1f;当然&#xff0c;那是在我们看到硬币落地的结果之后。但当硬币还在空中旋转时&#xff0c;它既不是正面也不是反面&#xff0c;而是正面和反面都有一定的可能性。 这个灰色地带就是量子计算的简…

入门 Go 语言

本专栏的 Go 语言学习参考了B站UP 软件工艺师的视频 本节需要&#xff1a; Go 语言环境VSCode 安装环境 下载 Go 环境&#xff0c;并安装下载 VSCode&#xff0c;安装。在 VSCode 中安装 Go 扩展&#xff1a; 接下来就可以编写 Go 语言了 第一条 Go Go 语言是一种编译型…

Oracle EBS R12.2 汉化

一、前言 在使用oracle ebs时&#xff0c;使用中文会更好的理解整个ebs流程&#xff0c;以下介绍oracle r12中文补丁的方式 如果你的系统除了支持英语外&#xff0c;还支持其他语言&#xff0c;比如中文&#xff0c;那你在下载补丁的时候除了下载Generic Platform版本外&#…

参考文献新国标GB/T 7714-2025的 biblatex 实现

参考文献新国标GB/T 7714-2025的biblatex实现 新版 GB/T 7714 目前正在修订和征求意见&#xff08;https://std.samr.gov.cn/gb/search/gbDetailed?id14CA9D282EB75AC8E06397BE0A0AEA2E&#xff09;。 根据已经呈现的草案&#xff0c;初步实现了biblatex样式(详见biblatex-gb…