其他分享
首页 > 其他分享> > 剑指offer 和为S的两个数字 (双指针)

剑指offer 和为S的两个数字 (双指针)

作者:互联网

题目描述

输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
输出描述:
对应每个测试案例,输出两个数,小的先输出。

Solution1

时间复杂度O(n),空间复杂度O(n)。

class Solution:
    def FindNumbersWithSum(self, array, tsum):
        import functools
        hashmap = {}
        ans = []
        for num in array:
            if num in hashmap.values():
                ans.append([tsum-num, num])
            else:
                hashmap[num] = tsum-num
        ans = sorted(ans, key=functools.cmp_to_key(self.cmp))
        if len(ans) > 0:
            return ans[0]
        else:
            return []

    def cmp(self, l, r):
        return l[0]*l[1] - r[0]*r[1]

Solution2

双指针法。时间复杂度O(n),空间复杂度O(1)。

假设:若b>a,且存在,
a+b=sa + b = sa+b=s
(am)+(b+m)=s(a - m ) + (b + m) = s(a−m)+(b+m)=s
则:(am)(b+m)=ab(ba)mmm<ab(a - m )(b + m)=ab - (b-a)m - m*m < ab(a−m)(b+m)=ab−(b−a)m−m∗m<ab。说明外层的乘积更小
也就是说依然是左右夹逼法!只需要2个指针。

  1. left开头,right指向结尾
  2. 如果和小于sum,说明太小了,left右移寻找更大的数
  3. 如果和大于sum,说明太大了,right左移寻找更小的数
  4. 和相等,把left和right的数返回
class Solution:
    def FindNumbersWithSum(self, array, tsum):
        start, end = 0, len(array)-1
        while start < end:
            sum_ = array[start]+array[end]
            if sum_ == tsum:
                return [array[start], array[end]]
            elif sum_ < tsum:
                start += 1
            elif sum_ > tsum:
                end -= 1
        return []

标签:tsum,return,数字,offer,sum,num,ans,array,指针
来源: https://blog.csdn.net/sunlanchang/article/details/101035388