由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
JobHunting版 - Re: leetcode第829题最优解
相关主题
大家刷第二遍 leetcode时候有什么感想。。。亚马逊电话第二轮
StefanPochmann简直算法大神阿给定整数数组和两个整数的和,求所有pair。
问一道题(5)求函数的极值那题的解法?
面试时如果遇到你见过或做过的题,应该告诉面试官吗?关于DP的问题
怎么处理面试官一点都不愿意交流的情况?程序员的思维太牛逼了 (转载)
问一个老题目nearest neighbours search算法
发个面经计算expression的函数
sqrt的数值解法 (转载)今天leetcode网站是不是down掉了?
相关话题的讨论汇总
话题: 829话题: leetcode话题: 最优话题: int话题: count
进入JobHunting版参与讨论
1 (共1页)
C*******4
发帖数: 1
1
问题:输入一个整数N,请问有多少种不同的方法把若干个连续的整数相加使得它们的
和为N?例如输入N=9,由于9 = 9、9 = 4 + 5、9 = 2 + 3 + 4,因此正确的输出是3。
分析:这是LeetCode第829题。
解法一:时间复杂度O(n)
我们可以想象有一个整数数组,数组里的第一个数字是1,第二个数字是2,以后的数字
以此类推。再假设有两个指针,第一个指针初始化指向数组的第一个数字,第二个指针
初始化指向数组的第二个数字。这两个指针就定位了一个子数组,该子数组由两个指针
之间的所有数字(包括两个指针指向的数字)组成。由于数组里的数字是连续递增的,
那么两个指针之间的任意子数组的数字也是连续递增的。
如果两个指针之间的子数组的所有数字之和小于输入的整数N,我们希望这个子数组包
含更多的数字,于是把第二个指针向右移动。每把第二个指针向右移动一位,相当于往
子数组的最右边添加一个新的数字,子数组的数字之和也会相应变大。如果此时子数组
的和仍然小于N,我们继续向右移动第二个指针。
如果子数组的和等于N,我们就找到了一个符合条件的子数组。接下来可以继续向右移
动第二个指针去寻找其他符合条件的子数组。
如果子数组的和大于N,我们希望子数组包含更少的数字,于是把第一个指针向右移动
。每把第一个指针向右移动一位,相当删除子数组最左边的数字,子数组的数字之和就
会相应变小。
这就是经典的双指针思路的应用。下面是根据这种思路写出的代码:
public int consecutiveNumbersSum(int N) {
int start = 1;
int end = 2;
int sum = 3;
int count = 1;
while (start <= N / 2) {
if (sum <= N) {
sum += end + 1;
end++;

if (sum == N) {
count++;
}
} else {
sum -= start;
start++;
}
}

return count;
}
在上述代码种,变量start相当于分析中的第一个指针,指向连续数字序列的最小的数
字(子数组的第一个数字);变量end相当于分析中的第二个指针,指向连续数字序列
的最大的数字(子数组的最有一个数字)。
上述代码中只有一个while循环,循环的每一次执行要么递增变量start,要么递增变量
end。由于start最多递增到N/2,而end最多也不会超过N。因此这种解法的时间复杂度
为O(n)。在LeetCode中,如果输入特别大的数字,比如大于10 ^ 8的数字,有可能超时。
解法二:O(n^0.5)
假设有k个连续的数字,它们的和为N。最小的k个连续的数字之和是1 + 2 + 3 + … +
k。从1开始的连续k个数字之和不一定等于N。可能存在一个整数i,(i + 1) + (i + 2)
+ (i + 3) + … + (i + k) = N。我们把这个等式稍微变换一下就有1 + 2 + 3 + …
+ k + i × k = N,也就是N - (1 + 2 + 3 + … + k) = i × k。
这个公式告诉我们,如果有k个连续的数字的和等于N,那么一定存在一个整数i,N 减
去1 + 2 + 3 + … + k的差等于i × k。也就是说N 减去1 + 2 + 3 + … + k的差一定
能被k整除。
1 + 2 + 3 + … + k的值很容易求出来,用一个从1开始的循环就能做到。下面是各种
思路的参考代码:
public int consecutiveNumbersSum(int N) {
int k = 1;
int sum = 0;
int count = 0;
while (sum < N) {
sum += k;
if (sum <= N && (N - sum) % k == 0) {
count++;
}

k++;
}

return count;
}
最后分析时间复杂度。上述代码中有一个while循环,循环一直执行到1 + 2 + 3 + …
+ k的结果大于N为止。由于1 + 2 + 3 + … + k等于k(k + 1) / 2,那么反过来如果输
入的整数是n,k的值最大也只能是O(n^0.5),因此第二种解法的时间复杂度是O(n^0.5)。
本文转载至"青云算法"微信公众号,欢迎大家一起来探讨更多解题。
d*******n
发帖数: 43
2
看题目感觉又是狗家的题
z*********n
发帖数: 1451
3
sqrt(n)的解法已经很naive了吧,我以为是贴了更巧妙的解法呢。
给定一个X,如果能被写成连续数字和,那就套下小学的等差数列求和,得出必然存在a
和n使得:
(a + (a + n - 1)) * n / 2 = x
x是给定目标数,已知,任务是求 a 和 n的整数解的个数
那最naive的办法就是用让n取1,2,3,4,... sqrt(2x),然后拿2X挨个除一下,把所有整
数a给找出来就行了。。。
这比你那个思路简单容易理解多了吧
d*******n
发帖数: 43
4
金刚兄让我明白了我为什么没拿到Google的offer

在a
有整

【在 z*********n 的大作中提到】
: sqrt(n)的解法已经很naive了吧,我以为是贴了更巧妙的解法呢。
: 给定一个X,如果能被写成连续数字和,那就套下小学的等差数列求和,得出必然存在a
: 和n使得:
: (a + (a + n - 1)) * n / 2 = x
: x是给定目标数,已知,任务是求 a 和 n的整数解的个数
: 那最naive的办法就是用让n取1,2,3,4,... sqrt(2x),然后拿2X挨个除一下,把所有整
: 数a给找出来就行了。。。
: 这比你那个思路简单容易理解多了吧

g****y
发帖数: 2810
5
这个题目我比赛错了6次

在a
有整

【在 z*********n 的大作中提到】
: sqrt(n)的解法已经很naive了吧,我以为是贴了更巧妙的解法呢。
: 给定一个X,如果能被写成连续数字和,那就套下小学的等差数列求和,得出必然存在a
: 和n使得:
: (a + (a + n - 1)) * n / 2 = x
: x是给定目标数,已知,任务是求 a 和 n的整数解的个数
: 那最naive的办法就是用让n取1,2,3,4,... sqrt(2x),然后拿2X挨个除一下,把所有整
: 数a给找出来就行了。。。
: 这比你那个思路简单容易理解多了吧

z*********n
发帖数: 1451
6
看ls这么一说,怕有啥坑没想到,赶快找到这题写了下,没发现有啥坑直接就pass了,
就按那个等差数列实现下就行了。
class Solution {
public int consecutiveNumbersSum(int target) {
int count = 0, t = 2 * target;
for (int n = 1; n < Math.sqrt(t); ++ n)
if (t % n == 0 && (t / n + 1 - n) % 2 == 0 )
count ++;
return count;
}
}
z*********n
发帖数: 1451
7

大宝建不但题刷的好,还这么谦虚,自叹不如啊。

【在 d*******n 的大作中提到】
: 金刚兄让我明白了我为什么没拿到Google的offer
:
: 在a
: 有整

m********u
发帖数: 3942
8
现在都800多题了??。。。
z*********n
发帖数: 1451
9

你们这行也关注刷题么。。。

【在 m********u 的大作中提到】
: 现在都800多题了??。。。
m********u
发帖数: 3942
10
哈哈 有时候问问刷到什么程度了。。。没刷好就先别面试了

【在 z*********n 的大作中提到】
:
: 你们这行也关注刷题么。。。

1 (共1页)
进入JobHunting版参与讨论
相关主题
今天leetcode网站是不是down掉了?怎么处理面试官一点都不愿意交流的情况?
CC150 a stack of boxes, find the greatest height问一个老题目
判断linkedlist是否palindrome最优解法是什么?发个面经
如果面试时给出的不是最优解,是否就完了?sqrt的数值解法 (转载)
大家刷第二遍 leetcode时候有什么感想。。。亚马逊电话第二轮
StefanPochmann简直算法大神阿给定整数数组和两个整数的和,求所有pair。
问一道题(5)求函数的极值那题的解法?
面试时如果遇到你见过或做过的题,应该告诉面试官吗?关于DP的问题
相关话题的讨论汇总
话题: 829话题: leetcode话题: 最优话题: int话题: count