题目及测试
package sword041;
/*
题目一:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。假设有多个数字的和等于s,输出随意一对就可以。
比如输入数组{1,2,4,7,11,15}和数字15.因为4+11=15。因此输出4和11.
题目二:输入一个正数s,打印出全部的和为s的连续正数序列(至少含有两个数字)。
比如输入15。因为1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续的序列1——5,4——6。7——8.
*/
import java.util.List;
public class main {
public static void main(String[] args) {
int[][] testTable = {
{1,2,4,7,11,15},{-1,-100,3,99}};
int[] testTable2={15,1};
for (int i=0;i<testTable.length;i++) {
test(testTable[i],testTable2[i]);
}
int[] testTable3 = {15,10,6};
for (int ito : testTable3) {
test2(ito);
}
}
private static void test(int[] ito,int ito2) {
Solution solution=new Solution();
long begin = System.currentTimeMillis();
for (int i = 0; i < ito.length; i++) {
System.out.print(ito[i]+" ");
}
System.out.println();
//开始时打印数组
System.out.println(ito2);
System.out.println( "rtn=" );
solution.findNumbersWithSum(ito,ito2);//执行程序
long end = System.currentTimeMillis();
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
private static void test2(int ito) {
Solution solution = new Solution();
long begin = System.currentTimeMillis();
System.out.print(ito);
System.out.println();
//开始时打印数组
System.out.println( "rtn=" );
solution.findContinuousSequence(ito);//执行程序
long end = System.currentTimeMillis();
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
题目1(成功)
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多个数字的和等于s,输出任意一对即可。
例如输入数组{1,2,4,7,11,15}和数字15.由于4+11=15,因此输出4和11.
很多人会立即能想到O(n2)的方法,也就是先在数组中固定一个数字,再依次判断数组中其余n-1个数字与它的和是不是等于s。
接着我们寻找更好的算法。我们先在数组中选择两个数字,如果他们的和等于输入的s,我们就找到了要找的两个数字。如果小于s呢?我们希望两个数字的和再大一点。由于数组已经排好序了,我们可以考虑选择较小的数字后面的数字。因为排在后面的数字要大一点,那么这两个数字的和也要大一点,就有可能等于输入的数字s了。同样,当两个数字的和大于输入的数字的时候,我们就可以选择较大的数字前面的数字了,因为排在前面的数字要小一些。
题目2(成功)
输入一个正数s,打印出所有的和为s的连续正数序列(至少含有两个数字)。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续的序列1——5,4——6,7——8.
有了前面的经验,我们也考虑用两个树small和big分别表示序列的最小值和最大值。首先把small初始化为1,big初始化为2.如果从small到big的序列的和大于s,我们可以从序列中去掉较小的值,也就是增大small的值。如果从small到big的序列的和小于s,我们可以增大big,让这个序列包含更多的数字。因为这个序列至少要有两个数字,我们一直增加small 到(1+s)/2为止。
package sword041;
class Solution {
public void findNumbersWithSum(int[] nums, int k) {
int length=nums.length;
if(length==0 || length == 1){
return;
}
int begin = 0;
int end = length -1;
while(begin <= end) {
int sum = nums[begin] + nums[end];
if(sum == k) {
System.out.println(nums[begin] + " "+ nums[end]);
return;
}
if(sum > k) {
end--;
}else {
begin++;
}
}
}
public void findContinuousSequence(int k) {
if(k <= 2) {
return;
}
int begin = 1;
int end = 2;
int sum = 3;
while(begin <= end && end <= k) {
if(sum == k) {
if(begin != end) {
System.out.println(begin + " "+ end);
}
end++;
sum+=end;
continue;
}
if(sum > k && begin != end) {
sum-=begin;
begin++;
}else {
end++;
sum+=end;
}
}
}
}