1. 程式人生 > >Leetccode 15. 三數之和(C語言快速排序+查詢)

Leetccode 15. 三數之和(C語言快速排序+查詢)

題目解析:

給定一個包含 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在這裡是一個全域性變數的引用,所以在主程式可以直接使用。
使用指標前一定要分配記憶體啊朋友們!一開始沒有分配記憶體經常報錯= =
還是太菜了= =