zoukankan      html  css  js  c++  java
  • 【Leetcode】两数之和,三数之和,四数之和

    两数之和

    题目

    给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

    你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

    示例:

    给定 nums = [2, 7, 11, 15], target = 9
    
    因为 nums[0] + nums[1] = 2 + 7 = 9
    所以返回 [0, 1]
    

    解答

    1,爆破,O(N^2)

    2,要找到任意 x + y = target,同等于 y = target - x,那么 把外层作为 x 遍历,查询 y 在不在列表即可,查询用哈希优化复杂度O(1)

    class Solution:
        def twoSum(self, nums: List[int], target: int) -> List[int]:
            hash_dict = {}
    
            for index, x in enumerate(nums):
                y = target - x
                if y in hash_dict:
                    return [hash_dict[y], index]
                hash_dict[x] = index
    

    三数之和

    题目

    给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

    注意:答案中不可以包含重复的三元组。

    例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
    
    满足要求的三元组集合为:
    [
      [-1, 0, 1],
      [-1, -1, 2]
    ]
    

    解答

    1,爆破,时间复杂度太高,O(N^3)。Time: O(N^3), Space: O(1)

    def threeSum(self, nums):
        # 爆破
        pass
    

    2,排序+双指针,外层遍历作为a,内层用双指针寻找b c,使得a+b+c=0。Time: O(N^2), Space: O(1)
    具体思路如下:

    标签:数组遍历
    首先对数组进行排序,排序后固定一个数 nums[i]nums[i],再使用左右指针指向 nums[i]nums[i]后面的两端,数字分别为 nums[L]nums[L] 和 nums[R]nums[R],计算三个数的和 sumsum 判断是否满足为 00,满足则添加进结果集
    如果 nums[i]nums[i]大于 00,则三数之和必然无法等于 00,结束循环
    如果 nums[i]nums[i] == nums[i-1]nums[i−1],则说明该数字重复,会导致结果重复,所以应该跳过
    当 sumsum == 00 时,nums[L]nums[L] == nums[L+1]nums[L+1] 则会导致结果重复,应该跳过,L++L++
    当 sumsum == 00 时,nums[R]nums[R] == nums[R-1]nums[R−1] 则会导致结果重复,应该跳过,R--R−−
    时间复杂度:O(n^2),n为数组长度
    
    class Solution:
        def threeSum(self, nums):
            if not nums or len(nums) < 3:
                return []
            nums.sort()  # 先排序
            ans = []
    
            lenth = len(nums)
            for i in range(lenth):  # 外层循环
                if nums[i] > 0:
                    break
                if i > 0 and nums[i] == nums[i - 1]:  # 防止相邻i相同出现重复值,不要比较i和i+1,因为当前i和i+1也许会和其他一个数组成一个元祖
                    continue
                L = i + 1
                R = lenth - 1
                while L < R:
                    sum = nums[i] + nums[L] + nums[R]
                    if sum < 0:
                        L += 1
                    elif sum > 0:
                        R -= 1
                    elif sum == 0:
                        ans.append([nums[i], 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 += 1  # 继续走
                        R -= 1
            return ans
    

    3,遍历外面两层a b,判断c在不在内层,内层用哈希表查找O(1)。Time: O(N^2), Space: O(N)

    def threeSum(self, nums):
        if len(nums) < 3:
            return []
        nums.sort()
        ans = set()
    
        for i, a in enumerate(nums[:-2]):
            if a > 0:
                break
            if i > 0 and a == nums[i-1]:
                continue
            hash_dict = {}
            for b in nums[i+1:]:
                if b not in hash_dict:  # 把 c 加入哈希表
                    hash_dict[-(a+b)] = 1
                else:
                    ans.add((a, -(a+b), b))
        return map(list, ans)
    
    
  • 相关阅读:
    金蝶k3 显示BOS序时簿并返回选中的值
    金蝶K3bos插件操作另一张单据
    H2.64的远程回放--开篇
    监控外网访问的几种方式
    ilbc编解码
    windows系统上安装与使用Android NDK r5 (转)
    安卓与PC网络对接实现视频实时播放
    WDR7500 花生壳问题
    要确保任何一次员工的晋升都符合公司的利益
    关于“部门建设”
  • 原文地址:https://www.cnblogs.com/ldy-miss/p/12060878.html
Copyright © 2011-2022 走看看