本文共 2752 字,大约阅读时间需要 9 分钟。
先前已经做过了两数之和,三数之和,现在到了四数之和,我在想有没有一个统一的方法可以针对k数之和去做,但是目前还没有找到一个适合与一个k数之和的方法(k>=2),今天先来看这道题目: 题意明确,相信很多刷过一些算法的同学看到题目的时候就会反射般的想到双指针,可是四数之和不同于三数之和,我们怎么样去用双指针做呢。在做三数之和的时候我们可以通过锁定一个数字,在进行左界右界的确定,在确定的范围中,寻找这个数字,那么我们将之泛化到四数之和中,既然三数之和我们确定了一个数字,那么在四数之和中,我们确定两个数字。锁定两个数字之和,确定左界和右界对范围内搜索。ok,思路明确,我们考虑特殊情况。
先对数组排序,使之为升序,这里可以使用冒泡,快排,选排,等等,任意选择。
c代码:
/*力扣 四数之和 c by ksks14 2020/11/10 13:31*//*思路,快排后利用双指针双面夹击,在思路上与三数之和几乎一样*/#define maxsize 2000int compare(const void* a, const void* b) { return *(int*)a - *(int*)b;}int** fourSum(int* nums, int numsSize, int target, int* returnSize, int** returnColumnSizes){ int **answer=(int**)malloc(sizeof(int*)*maxsize); *returnColumnSizes=(int*)malloc(sizeof(int)*maxsize); *returnSize=0;//初始化需要的变量 if(numsSize<4)//判断特殊情况 return answer; qsort(nums,numsSize,sizeof(int),compare); for(int i=0;i0&&nums[i]==nums[i-1])||(nums[i]+nums[numsSize-3]+nums[numsSize-2]+nums[numsSize-1] target)//求前四个数之和,若是大于target则根本没有符合的数字 break; //考虑两种特殊情况 for(int j=i+1;j i+1&&nums[j]==nums[j-1])||(nums[i]+nums[j]+nums[numsSize-2]+nums[numsSize-1] target) break; int l=j+1,r=numsSize-1; while(l l&&nums[r]==nums[r-1]) r--; l++,r--; } else if(target>nums[i]+nums[j]+nums[l]+nums[r]) l++; else r--; } } } return answer;}
python代码:(python思路与c相同,因此我借用网友代码,懒得动手😂)
class Solution: def fourSum(self, nums, target): ans = [] nums.sort() len_nums = len(nums) table = {val: index for index, val in enumerate(nums)} # 枚举前三个数 for i in range(len_nums-3): if i > 0 and nums[i] == nums[i-1]: continue if nums[i] * 4 > target: break if nums[i] + 3 * nums[-1] < target: continue for j in range(i + 1, len_nums-2): if j > i + 1 and nums[j] == nums[j-1]: continue if nums[i] + 3*nums[j] > target: break if nums[i] + nums[j] + 2*nums[-1] < target: continue for k in range(j + 1, len_nums-1): if k > j + 1 and nums[k] == nums[k - 1]: continue key = target - nums[i] - nums[j] - nums[k] if table.get(key, -1) > k: ans.append([nums[i], nums[j], nums[k], key])#key已经成为我们需要的值了
转载地址:http://ezcki.baihongyu.com/