Task04:查找2

一、1 两数之和

  • 题目描述
    给出一个整型数组nums,返回这个数组中两个数字的索引值i和j,使得nums[i] + nums[j]等于一个给定的target值,两个索引不能相等。如:nums= [2,7,11,15],target=9
    返回[0,1]
  • 分析
    遍历数组,每次遍历时将数组复制到temp中,判断target减去nums[i]后的值是否包含在数组temp中并将其删除,返回nums[i]在nums的坐标以及nums[j]在temp中的坐标+1。
  • 代码
class Solution:
    def twoSum(self, nums, target):
        for item in nums:
            temp = nums[:]
            num_2 = target - item
            temp.remove(item)
            if num_2 in temp:
                return [nums.index(item), temp.index(num_2)+1]

二、15 三数之和

  • 题目描述
    给出一个整型数组,寻找其中的所有不同的三元组(a,b,c),使得a+b+c=0
    注意:答案中不可以包含重复的三元组。
    如:nums = [-1, 0, 1, 2, -1, -4],
    结果为:[[-1, 0, 1],[-1, -1, 2]]
  • 分析
    对数组进行排序。
    遍历排序后数组:
    若 nums[i]>0:因为已经排序好,所以后面不可能有三个数加和等于 0,直接返回结果。
    对于重复元素:跳过,避免出现重复解
    令左指针 L=i+1,右指针 R=n−1,当 L<R,执行循环:
    当 nums[i]+nums[L]+nums[R]==0执行循环,判断左界和右界是否和下一位置重复,去除重复解。并同时将 L,R 移到下一位置,寻找新的解
    若和大于 0,说明 nums[R]太大,R左移
    若和小于 0,说明 nums[L] 太小,L右移
  • 代码
class Solution:
    def threeSum(self, nums):
        nums.sort()
        n = len(nums)
        ans = []
        for i in range(n):
            l = i + 1
            r = n - 1
            if nums[i] > 0:
                break
            if i > 0 and nums[i] == nums[i-1]:
                continue
            while l < r:
                if nums[i] + nums[l] + nums[r] == 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 = l + 1
                    r = r - 1
                elif nums[i] + nums[l] + nums[r] < 0:
                    l = l + 1
                else:
                    r = r - 1
        return ans

三、16 最接近的三数之和

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

输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。

  • 分析
    思路同找三个数之和为0一样

不同的是要得到三个数的和离target最近,也就是abs最小,在每次循环过程中更新最小的abs,并保存当前的三个数之和,循环结束返回保存的三数之和即可

  • 代码
class Solution:
    def threeSumClosest(self, nums, target):
        nums.sort()
        n = len(nums)
        res = abs(nums[0] + nums[1] + nums[2] - target)
        sum = nums[0] + nums[1] + nums[2]
        for i in range(n):
            l = i + 1
            r = n - 1
            if i > 0 and nums[i] == nums[i-1]:
                continue
            while l < r:
                if nums[i] + nums[l] + nums[r] == target:
                    return target
                else:
                    if abs(nums[i] + nums[l] + nums[r] - target) < res:
                        res = abs(nums[i] + nums[l] + nums[r] - target)
                        sum = nums[i] + nums[l] + nums[r]
                if nums[i] + nums[l] + nums[r] < target:
                    l = l+1
                else:
                    r = r - 1
        return sum

四、18 四数之和

  • 题目描述
    给出一个整形数组,寻找其中的所有不同的四元组(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]]

  • 分析
    思路同三数之和为0,往外多套一层循环

  • 代码

class Solution:
    def fourSum(self, nums, target):
        result = []
        nums.sort()
        for i in range(len(nums)):
            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
                l, r = j + 1, len(nums) - 1
                while l < r:
                    currSum = nums[i] + nums[j] + nums[l] + nums[r]
                    if currSum == target:
                        result.append([nums[i], nums[j], nums[l], nums[r]])
                        while l < r and nums[l] == nums[l + 1]:
                            l += 1
                        while l < r and nums[r] == nums[r - 1]:
                            r -= 1
                        l += 1
                        r -= 1
                    elif currSum < target:
                        l += 1
                    else:
                        r -= 1
        return result

五、49 字母异位词分组

  • 题目描述
    给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]
输出:
[
[“ate”,“eat”,“tea”],
[“nat”,“tan”],
[“bat”]
]

  • 分析
    把遇到的每一个字符串拆成列表,然后排序,然后再把排序后的列表转成字符串,放在字典里面判断。
  • 代码
class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        dict = {}
        for item in strs:
            key = tuple(sorted(item))
            dict[key] = dict.get(key, []) + [item]
        return list(dict.values())

六、 454 四数相加 II

  • 题目描述
    给出四个整形数组A,B,C,D,寻找有多少i,j,k,l的组合,使得A[i]+B[j]+C[k]+D[l]=0。其中,A,B,C,D中均含有相同的元素个数N,且0<=N<=500;

输入:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]
输出:
2

  • 分析
    初始化计数器 dic,dic 记录数组 A 和 B 元素的和,及其次数遍历数组 C 和 D,累加满足四数相加和为 0 的个数
  • 代码
class Solution:
    def fourSumCount(self, A: List[int], B: List[int], C: List[int], D: List[int]) -> int:
        dic = collections.Counter()
        ans = 0
        for a in A:
            for b in B:
                dic[a+b] += 1
        for c in C:
            for d in D:
                ans += dic[-c-d]
        return ans
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值