剑指offer---- 面试题57:和为s的两个数

题目描述

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

补充知识1.isinstance()

isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。

type() 不会认为子类是一种父类类型,不考虑继承关系。
isinstance() 会认为子类是一种父类类型,考虑继承关系。
如果要判断两个类型是否相同推荐使用 isinstance()。

1):
# >>>a = 2
# >>> isinstance (a,int)
True

例2):
class A:
    pass
class B(A):
    pass
isinstance(A(), A)    # returns True
type(A()) == A        # returns True
isinstance(B(), A)    # returns True
type(B()) == A        # returns False)

补充知识2.enumerate()

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

例:
seq = ['one', 'two', 'three']
for i, element in enumerate(seq):
    print(i, element)
输出:
0 one
1 two
2 three

思路1

两个游标i,j分别从开始和结尾的元素开始相加,>tsum 则j左移,<tsum 则i右移,=tsum 则输出,因为序列是从小到达的,所以第一个就是乘积最小的。

class solution():
    # 法一:
    def FindNumbersWithSum_1(self, array, tsum):
        left, right = 0, len(array)-1
        # ls=[]
        while left < right:
            if array[left] + array[right] > tsum:
                right -= 1
            elif array[left] + array[right] < tsum:
                left += 1
            else:
                return [array[left], array[right]]

s=solution()
print(s.FindNumbersWithSum_2([1,2,3,4,6,7,9,15],7))

思路2

用列表第一个和后面每一个元素相加,第二个和后面每一个元素相加,。。。直到v+v1=tsum,输出[v,v1]

class solution():
    def FindNumbersWithSum_2(self, array, tsum):
        # 法二:
        ls = []
        if not isinstance(array,list):
            return ls
        for i,v in enumerate(array):
            for v1 in array[i+1:]:
                if v+v1==tsum:
                    # ls.append([v,v1])
                    return [v,v1]
        # if ls:
        #     return ls[0]
        return ls

s=solution()
print(s.FindNumbersWithSum_2([1,2,3,4,6,7,9,15],7))

类似题目二:和为s的连续正数序列

题目描述:

小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列?

>> 和 <<都是位运算,
<< 是左移,相当于原数x乘2。比如整数4在二进制下是100,4<<1左移1位变成1000(二进制),结果是8。
>>是右移,相当于除以2。
# -*- coding:utf-8 -*-
class Solution:
    def FindContinuousSequence(self, tsum):
        """
        使用滑动窗口的方法来解决,
        设定一个动态的窗口,p_low指向窗口头部,
        p_high指向窗口尾部,窗口之间的值,为目标值。
        如果目标值为tsum,那就是其中一个解。否则移动窗口。
        :param tsum:
        """
        #错误判断处理,如果小于3的话 无解
        if tsum < 3:
            return []
        #设定初始的滑动窗口大小
        p_low = 1
        p_high = 2

        ans = []
        while p_low < p_high:
            #计算滑动窗口现在圈中的大小
            cur_sum = sum(range(p_low,p_high+1))
            if cur_sum == tsum:
                #找到一组解,并记录到ans数组中。
                ans.append(range(p_low,p_high+1))
                #移动滑动窗口,并寻找下一组解。
                p_high = p_high + 1
            elif cur_sum < tsum:
                p_high = p_high + 1
            else :
                p_low = p_low + 1
        return ans

if __name__ == '__main__':
    s = Solution()
    print  s.FindContinuousSequence(100)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值