和为S的连续正数序列
来源:互联网 发布:网络谣言研究报告 编辑:程序博客网 时间:2024/05/19 08:00
题目描述:
现在要求有多少种连续的正数序列的和为100(至少包括两个数)。其中一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列?
思路:
由于题目要求至少包含两个数,那么所有可能的序列的最大值均不会超过(sum + 1) >> 1;1, 2, start-1, start, start+1, start+2, ..., end-1 , end.于是,从 end= (sum + 1)>> 1, start = end - 1 开始求和。while( start > 0){ tmp += start; if(tmp == sum) 将 start, ..., end记录下来; tmp -= end; end--; start--; else if(tmp < sum) start--; else //tmp > sum tmp -= end; end--; start--; //每比较一次,需要更新start,end,tmp的值}时间复杂度为O(start) = O(sum)
代码实现如下:
import java.util.ArrayList;public class SequenceSum { public static void main(String[] args) { int target = 9; for (ArrayList<Integer> list : findSequence(target)) { for (int x : list) System.out.print(x + " "); System.out.println(""); } } private static ArrayList<ArrayList<Integer>> findSequence(int sum) { if (sum <= 2) return new ArrayList<>(); int end = (sum + 1) >> 1, start = end - 1, tmp = end; ArrayList<ArrayList<Integer>> aal = new ArrayList<>(); while (start > 0) { tmp += start; if (tmp == sum) { ArrayList<Integer> al = new ArrayList<>(); for (int i = start; i <= end; i++) { al.add(i); } aal.add(al); tmp -= end; end--; } else if (tmp > sum) { tmp -= end; end--; } start--; }}
输出如下:
4 5 2 3 4
也可以根据序列start从小到大输出序列
aal.add(0,al);
但是由于ArrayList是基于数组实现的,每次调用add(0,al)必然导致0以后的所有值需要后移一位,效率低下。可以将ArrayList换成LinkedList,这样效率会高一些,特别是链表较长时,效率会更高。
阅读全文
0 0
- 和为S的连续正数序列
- 和为S的连续正数序列
- 和为S的连续正数序列
- 和为s的连续正数序列
- 和为s的连续正数序列
- 和为s的连续正数序列
- 和为S的连续正数序列
- 和为S的连续正数序列
- 和为S的连续正数序列
- 和为s的连续正数序列
- 和为S的连续正数序列
- 和为S的连续正数序列
- 和为S的连续正数序列
- 和为S的连续正数序列
- 和为S的连续正数序列
- 和为S的连续正数序列
- 和为S的连续正数序列
- 和为S的连续正数序列
- Andro Studio 中JNI学习使用记录
- 阿里云推荐引擎使用教程
- 顺序栈和链栈的基本操作实现
- Java 校招面试,Google 面试官亲授-校招面试通关宝典
- 比特平面分层
- 和为S的连续正数序列
- 链表逆转的两种方法
- thinkphp3.2 发送邮件三个步骤
- BOM header
- thinkPHP传数组到模板页面volist每一列加一个button,点击按钮携带参数传给JS函数,跳转到不同的方法
- JQ 错误信息提示封装
- EF Code First 学习笔记:表映射
- iptables 详解(NAT)
- codevs 3983 调整(tweak)