和为S的连续正数序列
题目描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
代码语言:javascript复制public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
}
输出描述
输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
解析
将 1~(S/2 1)
区间的数 n
依次加入到队列中(因为从 S/2 1
之后的任意两个正数之和都大于 S
):
- 将
n
加入到队列queue
中并将队列元素之和queueSum
更新,更新queueSum
之后如果发现等于sum
,那么将此时的队列快照加入到返回结果res
中,并弹出队首元素(保证下次入队操作时队列元素之和是小于sum的) - 更新
queueSum
之后如果发现大于sum
,那么循环弹出队首元素直到queueSum<=Sum
,如果循环弹出之后发现queueSum==sum
那么将队列快照加入到res
中,并弹出队首元素(保证下次入队操作时队列元素之和是小于sum的);如果queueSum<sum
那么入队下一个n
于是有如下代码:
代码语言:javascript复制public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) { ArrayList<ArrayList<Integer>> res = new ArrayList(); if(sum <= 1){ return res; } LinkedList<Integer> queue = new LinkedList(); int n = 1, halfSum = (sum >> 1) 1, queueSum = 0; while(n <= halfSum){ queue.addLast(n); queueSum = n; if(queueSum == sum){ ArrayList<Integer> one = new ArrayList(); one.addAll(queue); res.add(one); queueSum -= queue.pollFirst(); }else if(queueSum > sum){ while(queueSum > sum){ queueSum -= queue.pollFirst(); } if(queueSum == sum){ ArrayList<Integer> one = new ArrayList(); one.addAll(queue); res.add(one); queueSum -= queue.pollFirst(); } } n ; }
return res;}
我们发现 11~15
和 20~24
行的代码是重复的,于是可以稍微优化一下:
public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) { ArrayList<ArrayList<Integer>> res = new ArrayList(); if(sum <= 1){ return res; } LinkedList<Integer> queue = new LinkedList(); int n = 1, halfSum = (sum >> 1) 1, queueSum = 0; while(n <= halfSum){ queue.addLast(n); queueSum = n; if(queueSum > sum){ while(queueSum > sum){ queueSum -= queue.pollFirst(); } } if(queueSum == sum){ ArrayList<Integer> one = new ArrayList(); one.addAll(queue); res.add(one); queueSum -= queue.pollFirst(); } n ; }
return res;}
出自:http://www.zhenganwen.top
已获授权