题目41-1:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,输出任意一对即可。
分析:
先选定第一个数字,然后将后面的数字依次遍历求和,并与需要的数字比较,需要n-1次,如果第一个数字不行,选择第二个,依次遍历求和。。。。需要n^2次,时间复杂度比较高,但也是可以的,在面试中,如果没有更好的办法写这个也是可以的,毕竟要比交白卷好得多,这里不展示此代码。
由于数组已经是排好序的,可以定义两个指针,第一个指向第一个元素,第二个指向最后一个元素;先拿第一个元素和最后一个元素相加,与要求的数字进行比较,如果大于,则将第二个指针向后移一位(索引值-1),再求和进行比较;如果小于,则将第一个指针向前移一位(索引值+1),再进行求和比较;直至找到结果。时间复杂度为O(n)。
代码如下所示:
public static int[] findNumberWithSum(int[] array, int sum) {
int[] result = new int[2];
if (array == null || array.length < 2 || sum < 0) {
return result;
}
int start = 0, end = array.length - 1;
while (start < end) {
long temp = array[start] + array[end];
if (temp == sum) {
result[0] = array[start];
result[1] = array[end];
return result;
} else if (temp > sum) {
end--;
} else {
start++;
}
}
return result;
}
public static void main(String[] args) {
// int[] result = findNumberWithSum(new int[]{1, 3, 5, 7, 8, 3, 5}, 10);
// int[] result = findNumberWithSum(new int[]{1, 3, 5, 7, 8, 3, 5}, 100);
int[] result = findNumberWithSum(new int[]{}, 10);
for (int r : result) {
System.out.print(r + " ");
}
}
题目41-2:输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5、5~6和7~8
。
分析:
用两个数small和big分别表示序列的最小值和最大值。首先把small初始化为1,big初始化为2。如果从small到big的序列的和大于s,我们可以从序列中去掉较小的值,也就是增大small的值。如果从small到big的序列的和小于s,我们可以增大big,让这个序列包含更多的数字。因为这个序列至少要有两个数字,我们一直增加small 到(1+s)/2为止。
以求和为9 的所有连续序列为例,过程如下表所示:
步骤 | small | big | 序列 | 序列和 | 与s相比 | 下一步操作 |
---|---|---|---|---|---|---|
1 | 1 | 2 | 1,2 | 3 | 小于 | 增加big |
2 | 1 | 3 | 1,2,3 | 6 | 小于 | 增加big |
3 | 1 | 4 | 1,2,3,4 | 10 | 大于 | 增加small |
4 | 2 | 4 | 2,3,4 | 9 | 等于 | 打印序列,增加big |
5 | 2 | 5 | 2,3,4,5 | 14 | 大于 | 增加small |
6 | 3 | 5 | 3,4,5 | 12 | 大于 | 增加small |
7 | 4 | 5 | 4,5 | 9 | 等于 | 打印序列 |
代码如下所示:
public static void findContinuousSequence(int sum) {
if (sum < 3) return;
int small = 1, big = 2, middle = (sum + 1) / 2, cur = small + big;
while (small < middle) {
if (cur == sum) findContinuousSequence(small, big);
while (cur > sum && small < middle) {
cur -= small;
small++;
if (cur == sum) findContinuousSequence(small, big);
}
big++;
cur += big;
}
}
public static void findContinuousSequence(int small, int big) {
for (int i = small; i <= big; i++) {
System.out.print(i + " ");
}
System.out.println();
}
public static void main(String[] args) {
findContinuousSequence(9);
System.out.println("-------------");
findContinuousSequence(4);
System.out.println("-------------");
findContinuousSequence(3);
}