LeetCode 面试题57 - II. 和为s的连续正数序列

面试题57 - II. 和为s的连续正数序列


题目来源:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/

题目


输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。

序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

示例 1:

输入:target = 9
输出:[[2,3,4],[4,5]]

示例 2:

输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]

解题思路


  • 思路:等差数列求和
  • 这里额外添加一个概念,末项与首项的间隔 i。利用间隔 i,当求得首项时,可根据间隔求得末项。
  • 尝试推导公式:

等差数列求和公式:

( x + y ) ∗ ( y − x + 1 ) 2 \frac{(x+y)*(y-x+1)}{2} 2(x+y)(yx+1)

其中这里 y 表示末项,x 表示首项。现在我们引入一个间隔的概念 i,那么可得 i = y − x i = y - x i=yx,将其代入上面的公式中:

( 2 x + i ) ∗ ( i + 1 ) 2 = t a r g e t \frac{(2x+i)*(i+1)}{2}=target 2(2x+i)(i+1)=target

上面的式子可简化成:

2 x i + 2 x + i 2 + i = 2 ∗ t a r g e t 2xi+2x+i^2+i=2*target 2xi+2x+i2+i=2target

最后可得:

x = t a r g e t − i ( i + 1 ) 2 i + 1 x = \frac{target-\frac{i(i+1)}{2}}{i+1} x=i+1target2i(i+1)

根据上面的公式就可以求得首项 x,在这里 x 必须是正整数,则 x ≥ 1 x \geq 1 x1,且题目提出序列至少有两个数,那么 i ≥ 1 i \geq 1 i1 i + 1 ≥ 2 i+1 \geq 2 i+12,将 x ≥ 1 , i + 1 ≥ 2 x \geq 1,i + 1 \geq 2 x1,i+12 两个限定条件代入式子中,可以得出限定条件 1

t a r g e t − i ( i + 1 ) 2 ≥ 2 target - \frac{i(i+1)}{2} \geq 2 target2i(i+1)2

同时,因为 x 必须是正整数,所以上面的式子中:

t a r g e t − i ( i + 1 ) 2 i + 1 \frac{target-\frac{i(i+1)}{2}}{i+1} i+1target2i(i+1)

这里所求得的结果,必须是整数,这就是限定条件 2。具体实现可用取模来判断。

那么根据这两个条件,用代码进行实现。

代码实现


class Solution:
    def findContinuousSequence(self, target: int) -> List[List[int]]:
    	# i 代表间隔,res 表示返回序列
        i, res = 1, []
		
		# 这里就是限定条件 1
        while target - i * (i + 1) * 0.5 >= 2:
	        # 先取模,看是否能整除
            mod = (target - i * (i + 1) * 0.5) % (i + 1)
            # 如果能整除,表示相除得到的是整数,这里可求得 x
            if not mod:
                x = int((target - i * (i + 1) * 0.5) / (i + 1))
                # 将 x 以及从 x 开始间隔 i 的所有数字添加到序列中
                res.append(list(range(x, x+i+1)))
            i += 1
        # 因为上面的结果是从间隔小的情况开始搜索
        # 题目中给出的答案是按照间隔较大的顺序返回
        # 所以将返回列表进行调转  
        return res[::-1]

实现效果


实现结果


以上就是 《和为s的连续正数序列》 的解题过程及实现。主要涉及的思路也是数学方法等差数列求和,不过这里引入了一个概念,就是首末两项的间隔。简化问题为求得首项的情况下,根据间隔得出末项。


欢迎关注微信公众号《书所集录》

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值