leetcode15和leetcode16 讲解和python实现

leetcode15 题目

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

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

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

leetcode16 题目

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

例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.

与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

为什么把这两个题目放在一起

   相信在你读完这两个题目后,会发现这两个题目"非常相似"(前者的target=0 后者的targrt=target 都是三个数),同时肯定是需要一定的技巧的,是不能暴力求解的

大致说一下解题思路(至于实现细节和边缘 大家自己看我的程序哈)

我们可以先对数组进行排序,如果是计算两个元素的和的话,我们会分别设置头和尾两个指针,向中间靠拢,那么三个的话,我们只需要先对第一个数进行循环取值下标i,剩下的两个指针分别指向i+1和数组的最后一个元素,这样的复杂度是 排序O(nlogn) + 查找O(n^2) = O(n^2)。

程序解答 (可以直接跑起来)

leetcode 15

class Solution:
    @staticmethod
    def threeSum(nums):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums=sorted(nums)
        print(nums)
        ans=[]
        isVisted=[]
        for i,num_1 in enumerate(nums):
            if num_1 in isVisted:
                continue
            else:
                isVisted.append(num_1)
            print(num_1)
            tmp=set()
            j=i+1
            k=len(nums)-1
            while j<k:
                num_2=nums[j]
                num_3=nums[k]
                sum=num_1+num_2+num_3
                if sum==0:
                    if len(tmp)>=1 and (num_2 in tmp):
                        pass
                    else:
                        ans.append([num_1,num_2,num_3]) #没有最小的
                        tmp.add(num_1)
                        tmp.add(num_2)
                        tmp.add(num_3)
                    j+=1
                    k-=1
                elif sum<0:
                    j+=1
                else:
                    k-=1
        return ans






if __name__=="__main__":
    print(Solution.threeSum([0,0,0,0]))

leetcode 16

class Solution:
    @staticmethod
    def threeSumClosest(nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums=sorted(nums)
        flag=0
        ans=0
        for i,num_1 in enumerate(nums):
            j=i+1
            k=len(nums)-1
            while j<k:
                num_2=nums[j]
                num_3=nums[k]
                sum=num_1+num_2+num_3
                if flag==0:
                    flag=1
                    ans=sum
                if abs(sum-target)<abs(ans-target):
                    ans=sum
                if sum==target:
                    return ans #没有最小的
                elif sum<target:
                    j+=1
                else:
                    k-=1
        return ans






if __name__=="__main__":
    print(Solution.threeSumClosest([-1,2,1,-4],1))

你可能感兴趣的:(常规算法题目)