《剑指offer》刷题——【面试中的各项能力】面试题57:和为s的数字(java实现)
(一)题目一:和为s的两个数字
一、题目描述
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于
S,输出两个数的乘积最小的。
二、题目分析
方法一:双循环-O(n^2)
- 先在数组中固定一个数字
- 再依次判断数组中其余的n-1个数字与它的和是不是等于s
方法二:双指针-O(n)
- 双指针,一个指向头,一个指向尾
- 求指针指向的两个数字的和:
- 若和=s,则指针指向的两个数字为所求
- 若和>s,则尾指针向前移动1步
- 若和<s,则头指针向后移动1步
代码实现
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
ArrayList<Integer> list = new ArrayList<Integer>();
if (array.length < 2 || array == null) {
return list;
}
int len = array.length;
int start = 0;
int end = len - 1;
while (start < end) {
if (array[start] + array[end] == sum) {
list.add(array[start]);
list.add(array[end]);
return list;
}
if (array[start] + array[end] > sum) {
end--;
}
if (array[start] + array[end] < sum) {
start++;
}
}
return list;
}
}
参考资料
(二)题目二:和为s的连续正数序列
一、题目描述
输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。
例如,输入15,打印出3个连续的序列1~5, 4~6, 7~8
二、题目分析
- 双指针,small,big分别指向序列中最小值和最大值
- 初始化:small=1, big=2
- 若small ~big的序列的和大于s,则增大small
- 若small ~big的序列的和小于s,则增大big
三、代码实现
import java.util.ArrayList;
public class Solution {
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
ArrayList<ArrayList<Integer> > result = new ArrayList<>();
int small = 1;
int big = 2;
while(big > small){
int curS = (small + big)*(big-small+1)/2;
if(curS == sum){
ArrayList<Integer> list = new ArrayList<>();
for(int i=small; i<=big; i++){
list.add(i);
}
result.add(list);
small++;
}
else if(curS < sum){
big++;
}
else{
small++;
}
}
return result;
}
}