• 剑指offer57:和为s的数字


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

    输入数组{1,2,4,7,11,15}和数字15,数组中4+11=15,因此输入4和11。

    首先分析这个数组是递增排序的,那么数组越往后,数组的值会越大,假设取数组中两个值A和B,A+B=19>s,那么想让和更小,只能往数组前面取比B还小的数字了;如果A+B=11<s,那么为了让和更大,就需要往数组后面取比A大的数字了。先处理数组头部和尾部的元素,看是否满足要求,不满足,根据比较策略,往中间找值,如果找到,就返回这一组数。go代码实现:

     1 func twoSum(nums []int, target int) []int {
     2     if len(nums) == 0 {
     3         return nil
     4     }
     5 
     6     var num[]int
     7     i := 0
     8     j := len(nums) - 1
     9     for i < j {
    10         if nums[i] + nums[j] == target {
    11             num = append(num, nums[i])
    12             num = append(num, nums[j])
    13             break
    14         } else if nums[i] + nums[j] < target {
    15             i++
    16         } else if nums[i] + nums[j] > target {
    17             j--
    18         }
    19     }
    20 
    21     return num
    22 }

    把上述题目稍作变换,得到另一个相似问题。

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

    分析:根据上一个题目的思路,还是选择根据当前序列和与目标值的大小关系,来从序列中删除、添加元素。首先从数字1、2开始处理,不断增大值,直到序列的和满足要求,题目要求所有的和为目标值的序列,找到一个后继续找。只能不断增大右区间值,缩小左区间值来往后找,因为题目要求至少含有两个数,所以,当左区间到(1+s)/2的时候,就不能再往后找了,再往后找两个值加起来肯定大于s了,所以,左区间的最大范围就是(1+s)/2了,基于分析思路,go实现代码:

     1 func findContinuousSequence(target int) [][]int {
     2     //序列要求至少包含两个数,1+2=3了,假设目标值<3,那就没有找的必要了
     3     if target < 3 {
     4         return nil
     5     }
     6 
     7     low := 1
     8     high := 2
     9     sum := low + high
    10     middle := (1 + target)/2
    11     var result[][]int
    12     for low < middle {
    13         //找到了一个满足要求的序列,打印出来
    14         if sum == target {
    15             //printfNum(low, high, result)
    16             result = append(result, printfNum(low, high)...)
    17         }
    18 
    19         //看看还有没有别的序列满足要求
    20         for low < middle && sum > target {
    21             sum = sum - low
    22             low ++
    23             if sum == target {
    24                 //printfNum(low, high, result)
    25                 result = append(result, printfNum(low, high)...)
    26             }
    27         }
    28 
    29         //要输出所有满足要求的序列,那就继续增大high的值,继续找
    30         high++
    31         sum = sum + high //更新sun值
    32     }
    33 
    34     return result
    35 }
    36 
    37 func printfNum(val1 int, val2 int) (result [][]int) {
    38     var num []int
    39     for val1 <= val2 {
    40         num = append(num, val1)
    41         val1++
    42     }
    43     result = append(result, num)
    44     return result
    45 }
  • 相关阅读:
    C#动态方法调用
    递归查询SQL语句
    Jquery获取下拉选择节点名称值赋给textbox文本框 获取 父节点的栏目名称编号
    C# 获取指定目录下所有文件信息
    引用借以记录借鉴 实现记住密码和自动登录功能
    摘用的一个实现在线发送短信接口功能
    Winform文件夹图片批量压缩整理修改
    安装包部署项目简述
    一道不错的考试题
    利用ItextSharp 生成PDF文档改进版
  • 原文地址:https://www.cnblogs.com/kks170716/p/15862725.html
Copyright © 2020-2023  润新知