15. 三数之和-c语言-快速排序+哈希表+二分查找

news/2024/12/5 4:45:56/

15. 三数之和-c语言-快速排序+哈希表+二分查找

给你一个整数数组 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 。

这题就不说那么多了,比较复杂,感兴趣学习一下,博主用了很多算法去优化:

/*** Return an array of arrays of size *returnSize.* The sizes of the arrays are returned as *returnColumnSizes array.* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().*/void quick_sort(int *a,int low,int high){int l=low,h=high;if(low<high){int p=a[low];while(low<high){while(low<high&&a[high]>=p){high--;}a[low]=a[high];while(low<high&&a[low]<=p){low++;}a[high]=a[low];}a[low]=p;quick_sort(a,l,low-1);quick_sort(a,low+1,h);}
}#define size 10000
struct hash{struct hash *next;int val;int index;
};
void add_hash(struct hash* h,int val,int index){struct hash*p=(struct hash *)malloc(sizeof(struct hash ));p->index=index;p->val=val;p->next=h->next;h->next=p;}bool find(struct hash *h,int val,int index1,int index2){struct hash*p=h->next;while(p){if(p->val==val&&index1!=p->index&&index2!=p->index){return true;}p=p->next;}return false;
}bool find2(struct hash *h,int val){struct hash*p=h->next;while(p){if(p->val==val){return true;}p=p->next;}return false;
}
int  find_b(int* nums,int numsSize,int val){int low=0;int high=numsSize-1;while(low<=high){int mid=(low+high)/2;if(nums[mid]>=val){high=mid-1;}else{low=mid+1;}}return high;}int cmp(const void* a, const void* b){return *(int*)a - *(int*)b;}int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){quick_sort(nums,0,numsSize-1);int p=numsSize*10;int sizet=0;int **re=(int** )malloc(sizeof(int*)*p);if(nums[0]>0||nums[numsSize-1]<0){*returnSize=sizet;return re;}* returnColumnSizes=(int* )malloc(sizeof(int)*p);for(int i=0;i<p;i++){re[i]=(int* )malloc(sizeof(int*)*3);(* returnColumnSizes)[i]=3;}struct hash *h=(struct hash *)malloc(sizeof(struct hash )*size);for(int i=0;i<size;i++){(h+i)->next=NULL;}struct hash *ht=(struct hash *)malloc(sizeof(struct hash )*size);for(int i=0;i<size;i++){(ht+i)->next=NULL;}for(int i=0;i<numsSize;i++){if(nums[i]>=0)add_hash(h+abs(nums[i])%size,nums[i],i);}int pre=nums[0]+1;for(int i=0;i<numsSize;i++){if(nums[i]!=pre){if(i+1==numsSize){continue;}int pret=nums[i+1]+1;int index=find_b(nums,numsSize,-nums[i]-nums[numsSize-1]);// printf("%d %d|| ",index,nums[i]);index=fmax(index,i+1);int j;for( j=index;j<numsSize; j++){if(nums[j]!=pret){if(nums[j]+nums[i]<=0){if(find2(ht+i%size,nums[j])==false){if(find(h+abs(nums[j]+nums[i])%size,abs(nums[j]+nums[i]),i,j)){re[sizet][0]=nums[i];re[sizet][1]=nums[j];re[sizet][2]=abs(nums[j]+nums[i]);sizet++;add_hash(ht+i%size,nums[j],-1);add_hash(ht+i%size,abs(nums[j]+nums[i]),-1);}}}else{break;}pret=nums[j];}}pre=nums[i];}}*returnSize=sizet;return re;}

http://www.ppmy.cn/news/3037.html

相关文章

如何解决跨域问题

什么是同源策略&#xff1f; 同源策略&#xff0c;它是由Netscape提出的一个著名的安全策略。 同源策略是浏览器的行为&#xff0c;是为了保护本地数据不被JavaScript代码获取回来的数据污染&#xff0c;因此拦截的是客户端发出的请求回来的数据接收&#xff0c;即请求发送了&…

CIDR格式网络策略值设置方式

CIDR的格式是IP网段/网络ID&#xff0c;斜杠左面的是网络IP段&#xff0c;斜杠右面是网络ID。如果网络用的是IPV4&#xff0c;它最大有效值是32&#xff0c;它的作用本质上是用来表示网络策略所用的子网掩码二进制里的1有多少个&#xff0c;也就是网络ID的位数。 传统的IPV4-t…

Redis框架(五):大众点评项目 商品目录 添加Redis缓存

大众点评项目 商品目录 添加Redis缓存需求&#xff1a;基于Redis查询商品信息业务实现给商品添加缓存给店铺类型添加缓存总结和业务流程SpringCloud章节复习已经过去&#xff0c;新的章节Redis开始了&#xff0c;这个章节中将会回顾Redis实战项目 大众点评 主要依照以下几个原则…

vivado tcl开发流程

本文以简单的led灯为例&#xff0c;阐述基于tcl的Vivado开发流程。 文件内容编写如下&#xff1a; led.v timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2022/12/12 14:57:22 // Design Name: // Module Name: alu // Project Name: // Target De…

CMake交叉编译工具编写

CMake交叉编译工具编写 CMake交叉编译工具编写CMake交叉编译工具编写前言一、编写toolchain.cmake二、编写CMakeLists.txt三、编写build.sh前言 在嵌入式设备应用时&#xff0c;需要在X86架构下编译板卡需要的ARM架构的文件&#xff0c;需要配置交叉编译器等来完成。这时就需要…

matlab智能算法之遗传算法

智能算法之遗传算法智能算法之遗传算法1.背景2.算法3.案例3.1 案例求解二元函数的最大值智能算法之遗传算法 1.背景 2.算法 3.案例 3.1 案例求解二元函数的最大值 例1&#xff1a;计算二元函数f(x,y)20x2y2−10∗(cos(2πx)cos(2πy))f(x,y)20x^2y^2-10*(cos(2\pi x)cos(2…

手写js——继承

原型链继承 所谓 函数 也就是 函数 Father其本身&#xff0c;也叫作构造函数 &#xff0c;当一个函数被创建的同时&#xff0c;也会为其创建一个 prototype 属性&#xff0c;而这个属性&#xff0c;就是用来指向 函数原型&#xff0c;的我们可以把 prototype 理解为 Father的一…

教育的本质——采用不同学习方式,学习者在两周后还能记住的内容有多少

目录 一、学习金字塔模型 二、学习曲线 三、左右脑交替学习法 一、学习金字塔模型 “学习金字塔模型”&#xff0c;人们学习的效率一共分为七个层次&#xff1a; 第一层 ~ 第四层&#xff1a;这是我们最熟悉不过的形式&#xff0c;在学生时代&#xff0c;老师在上面讲课、…