剑指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 }

 

posted @ 2022-02-04 13:22  星星里的花  阅读(33)  评论(0编辑  收藏  举报