一、排序法
1、解析/思路
Array_Merge(int* head,int low,int high,int* head1,int low1,int high1,int L,int Step_L,int Bool)
对两有序数组head、head1进行有序合并
Mer_Sort(int* head,int low,int high,int Step_L,int Bool)
对数组head进行二路归并
Seekaim(int* nums, int aim, int left, int right)
在数组nums的[left,right]区间查找aim,若存在则返回其下标,否则返回-1
流程:
二路归并创建nums的有序数组Temp
遍历Temp,在Temp的[i+1,numsSize]查找target-Temp[i]
若查询成功,则说明数组nums中存在两数之和等于target,最后在数组nums中寻找两数的下标
若查询失败,则说明数组nums中不存在两数之和等于target
2、代码
//有序数组调整
void Array_Merge(int* head,int low,int high,int* head1,int low1,int high1,int L,int Step_L,int Bool){
//i(逻辑),low+i*Step_L(实际)
//第一个数组最后的位置为((high-low)/Step_L)(逻辑),high(实际),长度:(high-low)/Step_L+1
//第二个数组最后的位置为((high1-low1)/Step_L)(逻辑),high1(实际),长度:(high1-low1)/Step_L+1
//复制
int Temp[((high-low)/Step_L+1)+((high1-low1)/Step_L+1)];//临时数组
int i=0,j=low,k=low1;//i指向Temp,指针j指向第1个数组,指针k指向第2个数组
if(Bool){//有序数组为从小到大
while(i<((high-low)/Step_L+1)+((high1-low1)/Step_L+1) && (j<=high || k<=high1)){
if(k>high1){//当第二个数组指针k越界说明第二个数组已经安排完毕
Temp[i]=head[j];
j+=Step_L;
i++;
continue;
}
if(j>high){//当第一个数组指针j越界说明第一个数组已经安排完毕
Temp[i]=head[k];
k+=Step_L;
i++;
continue;
}
if(head[j]<=head1[k]){//选择两指针中更小的数据
Temp[i]=head[j];
j+=Step_L;
}
else{
Temp[i]=head[k];
k+=Step_L;
}
i++;
}
}
else{//有序数组从大到小
while(i<((high-low)/Step_L+1)+((high1-low1)/Step_L+1) && (j<=high || k<=high1)){
if(k>high1){//当第二个数组指针k越界说明第二个数组已经安排完毕
Temp[i]=head[j];
j+=Step_L;
i++;
continue;
}
if(j>high){//当第一个数组指针j越界说明第一个数组已经安排完毕
Temp[i]=head[k];
k+=Step_L;
i++;
continue;
}
if(head[j]>=head1[k]){//选择两指针中更小的数据
Temp[i]=head[j];
j+=Step_L;
}
else{
Temp[i]=head[k];
k+=Step_L;
}
i++;
}
}
i=0;
while(i<((high-low)/Step_L+1))//将第一个数组复制到head
{
head[low+i*Step_L]=Temp[i];i++;}
while(i<((high-low)/Step_L+1)+((high1-low1)/Step_L+1))//将第二个数组复制到head
{
head1[low1+(i-((high-low)/Step_L+1))*Step_L]=Temp[i];i++;}
}
//二路归并排序
void Mer_Sort(int* head,int low,int high,int Step_L,int Bool){
int Shigh=low+(((high-low+1)/Step_L)-1+(((high-low+1)%Step_L)!=0))*Step_L;
int L=(Shigh-low)/Step_L+1;
if(L>2){
Mer_Sort(head,low,low+((L+1)/2-1)*Step_L,Step_L,Bool);
Mer_Sort(head,low+(((L+1)/2-1)+1)*Step_L,Shigh,Step_L,Bool);
}
if(L>1)Array_Merge(head,low,low+((L+1)/2-1)*Step_L,head,low+(((L+1)/2-1)+1)*Step_L,Shigh,L,Step_L,Bool);
}
//二分查找
int Seekaim(int* nums, int aim, int left, int right) {
//在[l,r]搜寻aim的位置,-1:不存在
if(nums[left] <= aim && aim <= nums[right]) {
while(left < right) {
if(nums[(left+right)/2] < aim) {
left = (left+right)/2+1;
}else {
right = (left+right)/2;
}
}
}
return nums[left] == aim?left: -1;
}
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
int* Temp = malloc(sizeof(int) * numsSize);
for(int i=0;i<numsSize;i++){
Temp[i]=nums[i];
}
Mer_Sort(Temp,0,numsSize-1,1,1);
for(int i=0;i<numsSize-1;i++){
int Index=Seekaim(Temp,target-Temp[i],i+1,numsSize-1);
//printf("\na:%d b:%d Index:%d",Temp[i],target-Temp[i],Index);
if(Index!=-1){
int* ret = malloc(sizeof(int) * 2);
ret[0]=Temp[i];
ret[1]=target-Temp[i];
*returnSize=2;
//printf("\n%d %d",ret[0],ret[1]);
int t0,t1;
for(int j=0;j<numsSize;j++){
if(nums[j]==ret[0]) {ret[0]=j;break;}
}
for(int j=0;j<numsSize;j++){
if(nums[j]==ret[1] && j!=ret[0]) {ret[1]=j;break;}
}
//printf("\n%d %d",ret[0],ret[1]);
return ret;
}
}
*returnSize=0;
return NULL;
}