NO.4 牛客网刷题|两数字和为S

前言:出差途中刷一题,总结一下思路。

题目描述:

输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

输出描述:

对应每个测试案例,输出两个数,小的先输出。

思路总结:刚看这道题的时候,注意题目几个关键信息,递增序列,查找,和为s,输出乘积最小。首先想到的是确定判断边界,要素s小于最第一个数的两倍或者s大于最后数的两倍,那么就不可能有解。或者输入数组是空集,那么也不可能有解。其次就是如何找到这个相加和为s的两个数了。我的思路是找到s/2在数列中的位置a以及下角标,再将数组以此分两部分,左边小于s/2,右边大于s/2。有想设置两个指针从中间分别向左和右移动,看其和是不是等于s。但是感觉太复杂,后来就用一个指针,从位置a向右移动到k值,再利用数组的特性,找到s-k的值。将所有找到的值存入列表中,那么结果中只需要返回最后一组数据就行。这个方法能顺利通过,但是不是最好的。(有想到二叉树的特性)

再深入题目的意思,要想两个值的积最小,那必然是头尾相差最大的两个数。同样的夹击的思路,从中间夹击不如从两边用两个移动的指针夹击,这样找到的第一个组解就是满足题目的解。根本不需要找到所有的解来判断乘积最小了。不需要太复杂的代码,主要是分析清楚题目的意思,理清逻辑关系。有些题目设计用数据结构,有些题目就是好好考虑潜在的数学特性,不一而足。

我的代码:(27s。5728k)

# -*- coding:utf-8 -*-
class Solution:
    def FindNumbersWithSum(self, array, tsum):
        # write code here
        #这道题有很强的数学性。
        if not array:  #判断是不是数组
            return array  #返回数组。如果是[],则返回[]
        n=len(array)  #数组长度
        num,j=0,0
        res=[]
        if tsum<array[0] or tsum>2*array[n-1]:  #边界条件
            return 0
        for i in range(n):
            if array[i]<=tsum/2:
                num+=1  #找到中间值的位置
        while num+j<n:  #下标应该小于n,一个指针开始查找/
            for number in array:  #@判断条件
                if number==tsum-array[num+j]:
                     res.append([number,array[num+j]])#将所有查找的两个数以一个数组的形式append进数组。
            j+=1
        if len(res)>0:  #判断结果存在否。
            return res[-1]
        else:
            return res

更新后的代码。(两边夹击  31s 5736k)

# -*- coding:utf-8 -*-
class Solution:
    def FindNumbersWithSum(self, array, tsum):
        # write code here
        #这道题有很强的数学性。

        if not array:  #判断是不是数组
            return array  #返回数组。如果是[],则返回[]
        n=len(array)  #数组长度
        i,j=0,n-1
        result=[]
        if tsum<array[0] or tsum>2*array[n-1]:  #边界条件
            return 0
        while i<j:
            if array[i]+array[j]>tsum:
                j-=1
            elif array[i]+array[j]<tsum:
                i+=1
            else:
                result.append([array[i],array[j]])
                break
        if len(result)==0:
            return result
        else:
            return result[0]
       

总结:两种解法对比,我的思路居然时间要短一些。有点类似于二分查找速度要快一些啊。重点掌握指针如何移动的操作以及break的用法。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值