剑指offer (python实现)

面试题41:和为s的两个数字VS和为s的连续正整数序列

题目一:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s,如果有多对数字的和等于s,输出任意一对即可。

分析:对于这个问题,最容易想到的就是现在数组中固定一个数字,再依次判断数组中其余的n-1个数字与它的和是不是等于s。这种做法的复杂度为O(n2)O(n2)。进一步优化算法:现在数组中选择两个数字,如果他们的和等于输入的s,就直接输出这两个数字,如果小于s,这个时候就希望两个数字的和大一点,我们知道数组是已经排好序的,所以可以考虑选择较小的数字后面的数字,因为排在后面的数字要大一些,那么两个数字的和也要大一些,就有可能等于输入的数字s了。同样的,当连个数字的和大于输入的数字的时候,我们可以选择较大数字前面的数字,因为排在数组前面的数字要小一些。

具体设计:
定义两个指针,第一个指向数组的第一个元素,另外一个指向数组的最后一个元素,然后把两个元素的和与s进行比较,如果相等则直接输出,如果两个元素的和比s小,则吧第一个指针向后移动一位,继续进行比较;相同的,如果两个元素的和比s大,则把第二个指针向前移动一位;直到找到第一个相等的便输出

代码实现(python)

class Solution:
    def findnumberWithSum(self,nums,s):
        if len(nums)<2:
            return
        ahead = 0
        behind = len(nums)-1
        while ahead < behind:
            if nums[ahead] + nums[behind] >s:
                behind -=1
            elif nums[ahead] +nums[behind] <s:
                ahead +=1
            else:
                print(nums[ahead],nums[behind])
                break
if __name__ == "__main__":
    S = Solution()
    nums = [1,2,4,7,11,16]

    S.findnumberWithSum(nums,10)

题目二:输入一个正数s,打印出所有和为s的连续整数序列(至少含有两个数),例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5、4~6和7~8

分析:和上面题目的想法一样,我们用两个数small 和big 分别表示序列的最小值和最大值。首先把small初始化为1,big初始化为2.如果从small到big的序列的和大于s,我们可以从序列中去掉较小的值,也就是增大small的值。如果从small到big的序列的和小于s,我们可以增大big,让这个序列包含更多的数字。因为这个序列至少要有两个数字,我们一直增大small到(1+s)/2为止。

代码实现(python):

# -*- coding:utf-8 -*-
class Solution:
    def FindContinuousSequence(self, tsum):
        # write code here
        nums = []

        if tsum < 3:
            return []
        small = 1
        big = 2
        middle = (1+tsum)//2
        curSum = small +big
        while small < middle:
            if curSum  == tsum:
                self.printSequence(nums,small,big)
            while curSum >tsum and small <middle:
                curSum -= small
                small +=1
                if curSum == tsum:
                    self.printSequence(nums,small,big)
            big +=1
            curSum +=big
        return nums




    def printSequence(self,nums,small,big):
        num = []
        for i in range(small,big+1):
            num.append(i)
        nums.append(num)
if __name__ == "__main__":
    S = Solution()
    S.FindContinuousSequence(3)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值