一、题目描述
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
二、思路分析及代码实现
方法一:穷举法
我们对数组进行两次遍历,最先找到的就是乘积最小的那一组
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
ArrayList<Integer> list=new ArrayList<>();
if(array==null||array.length<2){
return list;
}
int temp=Integer.MAX_VALUE;
int min=0;
int max=0;
for(int i=0;i<array.length-1;i++){
for(int j=i+1;j<array.length;j++){
if(array[i]+array[j]==sum){
if(array[i]*array[j]<temp){
min=array[i];
max=array[j];
temp=array[i]*array[j];
}
}
}
}
if(min!=max){
list.add(min);
list.add(max);
return list;
}
return list;
}
}
方法二:双指针法
思路分析:
考虑到输出的两个数的和相同,乘积最小。
数学知识分析可得,两个数差值越大,乘积越小。
我们从两端开始便利给定的数组,若两者的和刚好等于sum,则直接输出;若两者的和大于sum,则数值较大的数变小;否则数值较小的数变大。
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
ArrayList<Integer> list=new ArrayList<>();
if(array==null||array.length<2){
return list;
}
int index=0;
int lastindex=array.length-1;
while(array[index]<array[lastindex]){
if(array[index]+array[lastindex]==sum){
list.add(array[index]);
list.add(array[lastindex]);
break;
}else if(array[index]+array[lastindex]<sum){
index++;
}else lastindex--;
}
return list;
}
}
三、题目扩展
3.1 题目描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
输出描述
输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
3.2思路分析及代码实现
方法一:穷举法
import java.util.ArrayList;
public class Solution {
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
ArrayList<ArrayList<Integer>> list=new ArrayList<>();
if(sum<=0){
return list;
}
for(int i=1;i<sum;i++){
int j=i;
int sum1=0;
while(sum1<sum){
sum1=sum1+j;
j++;
}
if(sum1==sum){
ArrayList<Integer> list1=new ArrayList<>();
for(int k=i;k<j;k++){
list1.add(k);
}
list.add(list1);
}
}
return list;
}
}
方法二:双指针移动法
import java.util.ArrayList;
public class Solution {
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
ArrayList<ArrayList<Integer>> list=new ArrayList<>();
if(sum<=0){
return list;
}
int start=1;
int end=2;
int sum1=start+end;
while(sum>end){
if(sum1<sum){
end++;
sum1=sum1+end;
}else if(sum1>sum){
sum1=sum1-start;
start++;
}else{
ArrayList<Integer> list1=new ArrayList<>();
for(int i=start;i<=end;i++){
list1.add(i);
}
list.add(list1);
end++;
sum1+=end;
}
}
return list;
}
}
方法三:递归法
import java.util.ArrayList;
public class Solution {
private ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
private ArrayList<Integer> list = new ArrayList<Integer>();
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
for(int x=1; x<sum; x++){
FindSequence(x, sum);
}
return result;
}
public void FindSequence(int x, int sum){
if(sum < 0) return; //注意递归终止的条件应该是sum<0
list.add(x);
sum -= x;
if(sum == 0){
result.add(new ArrayList<Integer>(list));
}
FindSequence(x+1, sum);
list.remove(list.size() - 1);
}
}