日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

三数之和为0(c语言实现)(改进)

發布時間:2024/4/18 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 三数之和为0(c语言实现)(改进) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

暴力枚舉:暴力枚舉算法

改進算法:
主要函數
QS():由小到大快速排序
SearLR():尋找最大的負數以及最小的正數并返回
Seekaim():折半查找
Classify():分別尋找三零、一零、無零并輸出
Small_artillery():去重
threeSum():排除兩端為零
main():入口函數

#include <stdio.h> void QS(int *nums, int low, int high) {//需排序的片段首位序號if(high > low) {int low1 = low, high1 = high, flag = nums[low], temp;while(high1 > low1) {while(high1 > low1 && nums[high1] >= flag) high1--;nums[low1] = nums[high1];while(high1 > low1 && nums[low1] < flag) low1++;nums[high1] = nums[low1];}nums[low1] = flag;QS(nums, low, low1-1);QS(nums, low1+1, high);} }void SearLR(int* nums, int numsSize, int* retl, int* retr) {//最大的負數 and 最小的正數for(int i = 0; i < 6; i++) {}*retl = -1;*retr = numsSize;for(int i = 0; i < numsSize-1; i++) {if(nums[i] < 0) *retl = i;if(nums[numsSize-1-i] > 0) *retr = numsSize-1-i;} }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; }//按照三元組中0的個數(Num0)分類 //返回[n][3] void Classify(int* nums, int numsSize, int left, int right) {//尋找三零int z0;if(right-left>=4){printf("\n三零:%d %d %d", 0, 0, 0);}else{printf("\n三零:沒有");}printf("\n");//尋找一零if(right-left>=2){int i = 0, z = numsSize-1;while(i <= left) {z0=Seekaim(nums, -nums[i], right, z);if(z0 != -1) {z = z0;printf("\n一零:%d %d %d", 0, nums[i], -nums[i]);}i++;}}else{printf("\n一零:沒有");}printf("\n");//尋找無零int x = 0;while(x <= left) {int y = right,z = numsSize,z1=-1;while(y <= numsSize-1) {if(nums[x]+nums[y] > 0) {if(z>left) {z = left;}z0=Seekaim(nums, -(nums[x]+nums[y]), 0, z);if(z0 != -1) {z = z0;printf("\n無零:%d %d %d", nums[x], nums[y], -(nums[x]+nums[y]));break;}}else {if(z1<right){z1=numsSize;}z0=Seekaim(nums, -(nums[x]+nums[y]), y, z1);if(z0 != -1) {z1 = z0;printf("\n無零:%d %d %d", nums[x], nums[y], -(nums[x]+nums[y]));break;}}y++;}x++;} }void Small_artillery(int* nums, int numsSize, int left, int right) {//判斷L、R中間0的個數;以無0、一個0,三個0分類int flag=10^5+1,i=0,j=0;while(i<numsSize || nums[i]==0){if(nums[i]!=nums[j]){j++;nums[j]=nums[i];}i++;}numsSize=j+1;SearLR(nums, numsSize, &left, &right);Classify(nums,numsSize,left,right); }void threeSum(int* nums, int numsSize) {int** returnColumnSizes[10000][3], flag = -1;if(numsSize > 2) {QS(nums, 0, numsSize-1);int left, right;SearLR(nums, numsSize, &left, &right); //最大的負數 and 最小的正數if(left == -1 || right == numsSize) {//左邊界為0 or 右邊界為0if(right-left >= 4) {printf("\n三零:%d %d %d", 0, 0, 0);flag++;}else {printf("\n沒有");}}else {//排除邊界為0;判斷L、R中間0的個數;以無0、一個0,三個0分類Small_artillery(nums, numsSize, left, right);}}else {printf("\n沒有");} }int main(int argc, char **argv) {int nums[100] = {0,7,-4,-7,0,14,-6,-4,-12,11,4,9,7,4,-10,8,10,5,4,14,6,0,-9,5,6,6,-11,1,-8,-1,2,-1,13,5,-1,-2,4,9,9,-1,-3,-1,-7,11,10,-2,-4,5,10,-15,-4,-6,-8,2,14,13,-7,11,-9,-8,-13,0,-1,-15,-10,13,-2,1,-1,-15,7,3,-9,7,-1,-14,-10,2,6,8,-6,-12,-13,1,-3,8,-9,-2,4,-2,-3,6,5,11,6,11,10,12,-11,-14};threeSum(nums,100);return 0; }

總結

以上是生活随笔為你收集整理的三数之和为0(c语言实现)(改进)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。