剑指offer第二版(Python3)--面试题57 : 和为s的连续正数序列、和为s的数字

第2章 面试需要的基础知识

第3章 高质量的代码

第4章 解决面试题的思路

第5章 优化时间和空间效率

  面试题39 : 数组中出现次数超过一半的数字

  面试题40 : 最小的k个数

  面试题42 : 连续子数组的最大和

  面试题43 : 从1到n整数中1出现的次数

  面试题45 : 把数组排成最小的数

  面试题49 : 丑数

  面试题50 : 第一个只出现一次的字符

  面试题51 : 数组中的逆序对

  面试题52 : 两个链表的第一个公共结点

  面试题53 : 在排序数组中查找数字

  面试题55 : 二叉树的深度、平衡二叉树

  面试题56 : 数组中数字出现的次数

  面试题57 : 和为s的连续正数序列、和为s的数字

第6章 面试中的各项能力

第7章 两个面试案例


题目描述
牛客网

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

解题思路
  使用双指针前后夹逼,以数组[1, 2, 4, 7, 11, 15]为例,s=15。

  1. 第一个指针指向1,第二个指针指向15。发现两数之和为16,大于15,因此第二个指针后退一步,指向11;
  2. 此时两数之和为12,小于15,因此第一个指针前进一步,指向2;
  3. 此时两数之和为13,小于15,因此第一个指针前进一步,指向4;
  4. 此时两数之和为15,返回指针指向的数字,结束。

实战

def sequenceSum(lst, tsum):
    if not lst or tsum <= lst[0]:
        return -1

    start, end = 0, len(lst) - 1

    while start < end:
        sums = lst[start] + lst[end]
        if sums < tsum:
            start += 1
        elif sums > tsum:
            end -= 1
        else:
            return [lst[start], lst[end]]
    return -1

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

解题思路
  使用一个窗口遍历数字,窗口大小是动态的。当窗口内数字和大于S时,从窗口尾部删除小的数字,当窗口内数字和小于S时,加入一个数字到窗口中,每次删除和加入数字后都需要判断窗口内数字之和是否等于S,若等于则保留此时窗口作为一个序列。

实战
  代码中lst就是一个窗口,从1开始遍历数字直到 S // 2 + 1。
  需要特别注意的是results.append(lst[:])这一行,如果改成results.append(lst)会出错,因为lst始终在变化,例如lst=[2, 3, 4]时执行这一句results.append(lst),那么results中就是[[2, 3, 4]],但是之后lst.pop(0)后,lst变为[3, 4],此时results中也会跟着变为[3, 4]]。

class Solution:
    def FindContinuousSequence(self, tsum):
        # write code here
        if tsum <= 1:
            return []
        
        results, lst = [], []
        step = 0
        sums = 0
        while step < tsum // 2 + 1:
            if sums < tsum:
                step += 1
                sums += step
                lst.append(step)
            while sums >= tsum:
                if sums == tsum:
                    results.append(lst[:])
                    sums -= lst.pop(0)
                sums -= lst.pop(0)
        return results

你可能感兴趣的:(算法设计)