Leetccode 15. 三數之和(C語言快速排序+查詢)
阿新 • • 發佈:2019-02-13
題目解析:
給定一個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?找出所有滿足條件且不重複的三元組。
注意:答案中不可以包含重複的三元組。
第一個想法肯定是三層迴圈巢狀,但是題目中的不包含重複組讓我們的判斷變得異常困難,所以首先進行排序排序後遇到與前一個相同的數字就跳過,巢狀的第二層迴圈記錄剩下的首尾位置,首尾位置分別判斷網中間聚攏的過程中,若下一個數字與此時一致,則跳過這個數字。
程式碼:
我的程式碼寫出來魯棒性不太好,下面借鑑了一個網上胖友的程式碼跟我思路一樣,但寫的比我好
#include <stdio.h>
#include <stdlib.h>
void quickSort(int* nums,int first,int end){
int temp,l,r;
if(first>=end)return;
temp=nums[first];
l=first;r=end;
while(l<r){
while(l<r && nums[r]>=temp)r--;
if(l<r)nums[l]=nums[r];
while(l<r && nums[l]<=temp)l++;
if (l<r)nums[r]=nums[l];
}
nums[l]=temp;
quickSort(nums,first,l-1);
quickSort(nums,l+1,end);
} //快排程式碼
int** threeSum(int* nums, int numsSize, int* returnSize) {
int i,sum,top=-1,begin,end;
int** res=(int**)malloc(sizeof(int*)*(numsSize*(numsSize-1)*(numsSize-2))/6);
if(numsSize<3 ){
*returnSize=0;
return res;
} //組內元素小於三時直接返回;
quickSort(nums,0,numsSize-1);//快排;
for(i=0;i<numsSize;i++){
if(nums[i]>0)
break;//首元素大於0,跳出for,已經查詢到所有符合條件的三元組;
if(i>0 && nums[i]==nums[i-1])continue; //與上次迴圈的數一樣,跳過這個數,執行i++向下找;
begin=i+1;end=numsSize-1; //固定i後在i+1/尾兩處放入指標,開始迴圈;
while(begin<end){
sum=nums[i]+nums[begin]+nums[end];
if(sum==0){
top++;
res[top]=(int*)malloc(sizeof(int)*3);
res[top][0]=nums[i];res[top][1]=nums[begin];res[top][2]=nums[end];
begin++;end--;
while(begin<end && nums[begin]==nums[begin-1])begin++;
while(begin<end && nums[end]==nums[end+1])end--;
}
else if(sum>0) end--;
else begin++;
} //while
} //for
*returnSize=top+1; //top作為計數器,即為需要返回的長度;
return res;
}
int main()
{
int nums[6]={1,2,0,0,-2,0};
int *q;
q=nums;
int numsSize=6;
int* returnSize;
int **p;
returnSize=(int*)malloc(sizeof(int*));
p=(int**)malloc(sizeof(int*)*(numsSize*(numsSize-1)*(numsSize-2))/6);
p=threeSum(nums,numsSize,returnSize);
for(int i=0;i<*returnSize;i++)
{
for(int j=0;j<3;j++)
{
printf("%d ",*(*(p+i)+j));
}
printf("\n");
}
return 0;
}
returnSize在這裡是一個全域性變數的引用,所以在主程式可以直接使用。
使用指標前一定要分配記憶體啊朋友們!一開始沒有分配記憶體經常報錯= =
還是太菜了= =