【刷题日记】leetcode 两数/三数/四数之和+最接近的三数之和+较小的三数之和

leetcode1 两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

思路
返回下标,一般来说是不要排序了。
可以近似暴力搜索,但是是 O ( n 2 ) O(n^2) O(n2),写的不好会超时。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:

        lens = len(nums)
        j=-1
        for i in range(1,lens):
            temp = nums[:i]
            if (target - nums[i]) in temp:
                j = temp.index(target - nums[i])
                break
        if j>=0:
            return [j,i]

可以把数据做键,索引做键值存入hash表,在hash表中查找存不存在能配对的另一个元素
复杂度降为 O ( n ) O(n) O(n)

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:

        dic = {}
        for index,num in enumerate(nums):
            dic[num] = index
        for index,num in enumerate(nums):
            index2 = dic.get(target-num)
            if index2 and index2!=index:
                return [index,index2]
                

leetcode167: 升序数组的两数之和

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。

函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。

说明:

返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:

输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        left,right = 0,len(numbers)-1
        while left<right:
            if numbers[left]+numbers[right] == target:
                return [left+1,right+1]
            elif numbers[left]+numbers[right] < target:
                left+=1
            else:
                right-=1
        return []

leetcode15 三数之和

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

注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

固定第一个数,剩余两个数用两个指针查找。
注意去重。

  1. 固定的第一个数去重(遍历时相同则跳过)
  2. 双指针指向的数去重(局部遍历时相同则跳过)
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        res,k=[],0
        for k in range(len(nums)-2):
            if nums[k]>0:break
            if k>0 and nums[k] == nums[k-1]:continue # 跳过相同的nums[k]
            i,j = k+1,len(nums)-1
            while i<j:
                s = nums[i]+nums[j]
                if s<-nums[k]:
                    i+=1
                    while i<j and nums[i]==nums[i-1]:
                        i+=1 #跳过相同的nums[i]
                elif s>-nums[k]:
                    j-=1
                    while i<j and nums[j] == nums[j+1]:
                        j-=1
                else:
                    res.append([nums[k],nums[i],nums[j]])
                    i+=1
                    j-=1
                    while i<j and nums[i] ==nums[i-1]:i+=1
                    while i<j and nums[j] == nums[j+1]:j-=1
        
        return res

leetcode18 四数之和

给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

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

示例:
给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。
满足要求的四元组集合为:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]

思路
如果直接类比三数和,那就是固定两个数,另外两个数用双指针查找,复杂度时 O ( n 3 ) O(n^3) O(n3)

为了避免重复,可以先用set保存结果(自动去重,set添加元素的方法是set.add()
然后再把set中的元素放入list
for item in set_xx: list_xx.append(list(item)

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        nums.sort()
        res = set()
        for i in range(len(nums)-3):
            for j in range(i+1,len(nums)-2):
                left,right = j+1,len(nums)-1
                new_tar = target-nums[i]-nums[j]
                while left<right:
                    su = nums[left]+nums[right]
                    if su<new_tar:
                        left+=1
                    elif su>new_tar:
                        right -=1
                    else:
                        res.add((nums[i],nums[j],nums[left],nums[right]))
                        left+=1
                        right-=1
        rec = []
        for i in res:
            rec.append(list(i))
        return rec

leetcode16 最接近的三数之和

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:        
        nums.sort()
        #print(nums)
        n = len(nums)
        res = float("inf")
        for i in range(n-2):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            left = i + 1
            right = n - 1
            while left < right :
                #print(left,right)
                
                cur = nums[i] + nums[left] + nums[right]
                if abs(res-target) > abs(cur-target):
                    res = cur
                if cur == target:
                    return target              
                elif cur > target:
                    right -= 1
                else:
                    left += 1
        return res

leetcode259 较小的三数和

oh。。没权限。。之后再补

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值