leetcode的三数之和与四数之和

  • 三数之和;给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组
  • 四数之和;给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复)

        题目特点:这两题有一个特点就是三元组(四元组)不能重复

        解决方法:双指针

三数之和:

  1. 首先对nums进行排序(这里按照升序排序),并计算nums长度,记为nums_l
  2. 将nums[i]作为为三元组的第一个数
  3. 左指针left存放索引(i+1),右指针right存放索引(nums_l - 1),将nums[left] 于 nums[right]作为三元组第二个数与第三个数。
  4. 判断nums[i] + nums[left] + nums[right] 是否等于目标值(target,在三数之和中,target值为0),若值小于目标值,则 left += 1,若值大于目标值,则right -= 1,若为0,则存入列表(res)并将left向右移,直到 left 指向的值不同于之前的值,同理,right 向左移动,直到 right 指向的值不同于之前的值。在移动的过程中需要满足 left < right,若满足则继续移动,若不满足则跳出指针移动循环。
  5. 回到2,从索引 i 开始,往右寻找第一个不等于nums[i]的数,作为三元组的第一个数,重复3、4、5操作
nums_l = len(nums)
nums.sort(reverse=False)
res = []
for i in range(nums_l):
    if i >= 1 and nums[i] == nums[i-1]:
        continue
    left = i + 1
    right = nums_l - 1
    while left < right:
        total = nums[i] + nums[left] + nums[right]
        if total < 0: 
			left += 1
        elif total > 0: 
			right -= 1
        else:
            res.append([nums[i], nums[left], nums[right]])
            while left != right and nums[left] == nums[left+1]:
                left += 1
            while left != right and nums[right-1] == nums[right]:
                right -= 1
			left += 1
			right -= 1
		        
return res

四数之和:

整体思路于三数之和类似,差别在于要多加一层循环,在三数之和中事先确定一个数,在四数之和中需要确定两个数。

  1. 首先对nums进行排序(这里按照升序排序),并计算nums长度,记为nums_l
  2. 确定nums[i]确认为四元组的第一个数,确定nums[j] = nums[i+1]为四元组的第二个数
  3. 左指针left存放索引(j+1),右指针right存放索引(nums_l - 1)
  4. 判断nums[i] + nums[j] + nums[left] + nums[right] 是否等于目标值,left和right的操作于三数之和相同
  5. 在nums中,从 j 开始,寻找第一个不等于nums[j]的数,四元组的第二个数,并重复3、4、5,当 j 到达nums的末尾时,则跳回到步骤2。
nums.sort()
nums_l = len(nums)
res = []
for i in range(nums_l):
    if i > 0 and nums[i] == nums[i - 1]:
        continue
    for j in range(i + 1, nums_l):
        if j > i + 1 and nums[j] == nums[j - 1]:
            continue
        left = j + 1
        right = nums_l - 1
        while left < right:
            total = nums[i] + nums[left] + nums[right] + nums[j]
			if total < target:
				left += 1
			elif total > target:
				right -= 1
            elif total == target:
                res.append([nums[i], nums[left], nums[right], nums[j]])
                while left < right and nums[left] == nums[left+1]: left += 1
                while left < right and nums[right-1] == nums[right]: right -= 1
                left += 1
                right -= 1
return res

参考:

三数之和来源:力扣(LeetCode) 链接:力扣

四数之和来源:力扣(LeetCode) 链接:力扣

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值