zoukankan      html  css  js  c++  java
  • 16. 3Sum Closest

    题目:

    Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

        For example, given array S = {-1 2 1 -4}, and target = 1.
    
        The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
    

    代码:

    做过第15题:3Sum之后,看到该问题,不会很陌生,只不过这次目标值不在是0,而是尽可能接近一个传入的参数

    同样先尝试了遍历3遍,也就是O(n^3)时间复杂度,不出所料,超时。

    于是,根据上一题的经验,先确定第一个数字,之后在剩余数字中定义两端的两个指针,一个最大一个最小,根据三数相加和目标值比较的结果,分别移动左右两端的指针,增加或缩小三数的和,靠近目标值。

    代码已经加入详细注释,根据之前的经验自己写的,调试了很久。还有很多不足,共同学习,望大神多多指教:

    def threeSumClosest(self, nums, target):
            """
            :type nums: List[int]
            :type target: int
            :rtype: int
            """
            if len(nums) < 3: return 0
            #排序
            nums.sort()
            res = 0
            result = []
            flag = []
            length = len(nums)
            for i in range(0, length - 2):
                if i and nums[i] == nums[i - 1]:
                    continue
                left, right = i + 1, length - 1
                while left < right:   
                    #如果三数字相加结果等于目标值,直接返回结果
                    if nums[i] + nums[left] + nums[right] == target:
                        #print(left,right, "equal ",nums[i], nums[left],  nums[right])
                        res = target
                        return res
                    #如果三数字相加结果大于目标值,右边的数字指针减小
                    elif nums[i] + nums[left] + nums[right] > target:
                        print(left,right, "big ",nums[i], nums[left],  nums[right])                      
                        res =  nums[i] + nums[left] + nums[right]
                        right -= 1
                        #如果指针指向的下一个数字和该数字相同,则指针继续向左移动
                        while left < right and nums[right]==nums[right+1]:
                            right -= 1
                        #由于存在移动一位之后三数字相加和突然小于目标值的情况,所以需要记录该值来比较
                        #否则下一轮循环之后的值和目标值得差可能比当前更大
                        if nums[i] + nums[left] + nums[right] < target:
                            result.append(res)
                            flag.append(abs(res-target))   
                    #如果三数字相加结果小于目标值,左边的数字指针增加        
                    else:
                        print("little ",nums[i], nums[left],  nums[right])                  
                        res =  nums[i] + nums[left] + nums[right]
                        left += 1
                        #如果指针指向的下一个数字和该数字相同,则指针继续向右移动
                        while left < right and nums[left]==nums[left-1]:
                            left += 1
                        #由于存在移动一位之后三数字相加和突然大于目标值的情况,所以需要记录该值来比较
                        #否则下一轮循环之后的值和目标值得差可能比当前更大
                        if nums[i] + nums[left] + nums[right] > target:
                            result.append(res)
                            flag.append(abs(res-target))   
                #result分别存储不同的第一个数字遍历后最接近目标值的结果
                #flag对应存储不同结果和目标值之间的差
                result.append(res)
                flag.append(abs(res-target))
            print (result,' ',flag)
            #返回差距最小的结果即可    
            return (result[flag.index(min(flag))])

  • 相关阅读:
    Git教程
    test
    Android中的权限机制
    Android中<uses-library>的理解
    权限机制
    总是听到有人说AndroidX,到底什么是AndroidX?Android和AndroidX的区别
    VMware Tools按钮变灰色,无法安装的解决方法
    VMware Tools (ubuntu系统)安装详细过程与使用
    Android studio常用快捷键
    CVE漏洞分析
  • 原文地址:https://www.cnblogs.com/yuanzhaoyi/p/6048031.html
Copyright © 2011-2022 走看看