18.四数之和

mac2025-06-18  5

18.四数之和

题解排序+双指针算法流程:剪枝条件:复杂度分析PythonJava(待完成)

题解

排序+双指针

和三数之和一样,本题的难点依旧在于如何去除重复解 取两个数组合,将问题转化为三数之和

算法流程:

特判,对于数组长度 n n n,如果数组为Null或者数组长度小于4,返回 [ ] [] []。对数组进行排序。遍历排序后数组: 对于重复元素,跳过,条件: i > 0 且 n u m s [ i ] = = n u m s [ i − 1 ] i>0 且 nums[i]==nums[i-1] i>0nums[i]==nums[i1],避免出现重复解二次遍历,重复元素跳过,判断重复元素从 i i i后第二个元素开始,所以条件: j − i > 1 且 n u m s [ j ] = = n u m s [ j − 1 ] j-i>1 且 nums[j]==nums[j-1] ji>1nums[j]==nums[j1]令左指针 L = j + 1 L=j+1 L=j+1,右指针 R = n − 1 R=n-1 R=n1,当 L < R L<R L<R时,执行循环: *当 n u m s [ i ] + n u m s [ j ] + n u m s [ L ] + n u m s [ R ] = = t a r g e t nums[i]+nums[j]+nums[L]+nums[R]==target nums[i]+nums[j]+nums[L]+nums[R]==target时,将结果加入 r e s res res并执行循环,判断左界和右界是否和下一位置重复,以去除重复解。并同时将 L , R L,R L,R移到下一位置,寻找新的解 *若和大于0,说明 n u m s [ R ] nums[R] nums[R]太大, R R R左移 *若和小于0,说明 n u m s [ L ] nums[L] nums[L]太小, L L L右移

剪枝条件:

对于本题,按照上述流程写下来,可以通过。 我们继续对算法进行剪枝优化 第一次遍历

n u m s [ i ] + n u m s [ i + 1 ] + n u m s [ i + 2 ] + n u m s [ i + 3 ] > t a r g e t nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target,则可以退出,因为最小四数之和大于目标,则不可能存在结果。**注意:**和三数之和的优化条件不同,三数之和中 t a r g e t = 0 target=0 target=0,所以只要 n u m s [ i ] > 0 nums[i]>0 nums[i]>0,则可退出,这里则需要更为严格的条件。若当前值和数组中最大的三个值相加依旧小于目标, n u m s [ i ] + n u m s [ n − 1 ] + n u m s [ n − 2 ] + n u m s [ n − 3 ] < t a r g e t nums[i] + nums[n- 1] + nums[n- 2] + nums[n- 3] < target nums[i]+nums[n1]+nums[n2]+nums[n3]<target,则continue

第二次遍历

同理,若 n u m s [ i ] + n u m s [ j ] + n u m s [ j + 1 ] + n u m s [ j + 2 ] > t a r g e t nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target nums[i]+nums[j]+nums[j+1]+nums[j+2]>target,break n u m s [ i ] + n u m s [ j ] + n u m s [ n − 1 ] + n u m s [ n − 2 ] < t a r g e t nums[i] + nums[j] + nums[n - 1] + nums[n - 2] < target nums[i]+nums[j]+nums[n1]+nums[n2]<target,continue

复杂度分析

时间复杂度: O ( n 3 ) O\left(n^{3}\right) O(n3),数组排序 O ( N log ⁡ N ) O(N \log N) O(NlogN),两次遍历数组 O ( n 2 ) O\left(n^{2}\right) O(n2),双指针遍历 O ( n ) O\left(n\right) O(n),总体 O ( N log ⁡ N ) + O ( n 2 ) ∗ O ( n ) O(N \log N)+O\left(n^{2}\right)*O\left(n\right) O(NlogN)+O(n2)O(n) O ( n 3 ) O\left(n^{3}\right) O(n3)空间复杂度: O ( 1 ) O(1) O(1)

Python

class Solution: def fourSum(self, nums: List[int], target: int) -> List[List[int]]: n=len(nums) if(not nums or n<4): return [] nums.sort() res=[] for i in range(n-3): if(nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target): break if(nums[i]+nums[-1]+nums[-2]+nums[-3]<target): continue if(i>0 and nums[i]==nums[i-1]): continue for j in range(i+1,n-2): if(nums[i]+nums[j]+nums[j+1]+nums[j+2]>target): break if(nums[i]+nums[j]+nums[-1]+nums[-2]<target): continue if(j-i>1 and nums[j]==nums[j-1]): continue L=j+1 R=n-1 while(L<R): if(nums[i]+nums[j]+nums[L]+nums[R]==target): res.append([nums[i],nums[j],nums[L],nums[R]]) while(L<R and nums[L]==nums[L+1]): L=L+1 while(L<R and nums[R]==nums[R-1]): R=R-1 L=L+1 R=R-1 elif(nums[i]+nums[j]+nums[L]+nums[R]>target): R=R-1 else: L=L+1 return res

优化后,有明显提升

Java(待完成)

最新回复(0)