(python刷题)leetcode 第18题:四数之和

题目在leetcode上的链接为:
https://leetcode-cn.com/problems/4sum/

题目描述
在这里插入图片描述
解题思路
这一题与第15题 三数之和 的解题思路类似。先对数组进行从小到大的排序,然后使用两重循环遍历数组,再使用双指针遍历一遍即可。
具体步骤为:

  • 首先如果 nums 为 None,或者 nums 长度小于4,那么返回空列表
  • 将 nums 按照从小到大进行排序
  • 使用变量 i 循环遍历 nums:
    • 如果 i>0 且 nums[i]=nums[i-1],说明前一步中已经考虑了这一步可能存在的四个数的结果,那么 continue 不执行之后的代码,以此进行去重操作(第一次去重)
    • 使用变量 j 循环遍历 nums[i+1:]
      • 如果 j>i+1 且 nums[j]=nums[j-1],则 continue 不执行之后的代码,以此进行去重操作(第二次去重)
      • 令左指针 left 为 j+1,右指针 right 为 len(nums)-1
      • 以 left<right 作为判断条件进入循环:
        • 如果 nums[i]+nums[j]+nums[left]+nums[right] 等于 target:
          • 将找到的四个数添加到结果中
          • 循环判断如果左右指针位置的数等于它门下一个位置的数时,就将指针移到下一个位置进行去重操作 (第三次去重)
          • 将左右指针都移到下一个位置重新找下一个可能的结果
        • 如果 nums[i]+nums[j]+nums[left]+nums[right] 小于 target,说明太小了,则将左指针向右移动一步
        • 如果 nums[i]+nums[j]+nums[left]+nums[right] 大于 target,说明太大了,则将右指针向左移动一步

ps: 要注意算法中标明的三次去重操作,其中第一次和第三次的去重操作与 三数之和 中的一样,特别注意第二次去重操作中的条件 j>i+1,因为当 j=i+1 时,nums[j-1]=nums[i],此时比较的 nums[j]=nums[j-1]=nums[i] 是将 i 与 j 位置的数进行比较,但我们需要比较的是 j 位置的数与它之前自己走过的前一步的数是否相同,所以需要条件 j>i+1,让 j 与 i 不相邻时再比较决定是否对 j 进行去重操作

复杂度分析:
排序操作的时间复杂度为 o(nlog(n)),三重循环的复杂度为 o(n3),由于这两步操作是顺序执行,所以总的时间复杂度为 o(nlog(n))+o(n3),即为 o(n3)。
由于只需要常数级的存储空间,所以空间复杂度为 o(1)

python代码

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        if not nums or len(nums) < 4:
            return []
        nums.sort()
        if (target >= 0 and nums[0] > target) or (target < 0 and nums[len(nums) - 1] < target):
            return []
        res = []
        for i in range(len(nums)):
            if target >= 0 and nums[i] > target:
                return res
            if i > 0 and nums[i] == nums[i - 1]:
                continue
            for j in range(i + 1, len(nums)):
                if j > i + 1 and nums[j] == nums[j - 1]:
                    continue
                left = j + 1
                right = len(nums) - 1
                while left < right:
                    if nums[i] + nums[j] + nums[left] + nums[right] == target:
                        res.append([nums[i], nums[j], nums[left], nums[right]])
                        while left < right and nums[left] == nums[left + 1]:
                            left += 1
                        while left < right and nums[right] == nums[right - 1]:
                            right -= 1
                        left += 1
                        right -= 1
                    elif nums[i] + nums[j] + nums[left] + nums[right] > target:
                        right -= 1
                    else:
                        left += 1
        return res
发布了37 篇原创文章 · 获赞 6 · 访问量 5381

猜你喜欢

转载自blog.csdn.net/qq_37891889/article/details/104354408
今日推荐