剑指offer——和为S的两个数字
输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
自己的解法:
非常的麻烦
先把array的数组放入一个Map(Map中的数字范围中要小于sum)中,键即为该数字,然后利用迭代器遍历map,事先准备一个长度为array的数组res,存在两数之和相加为sum时,就把这一对数放入事先准备的数组res中,再利用迭代器把相关数删除。
最后遍历res数组,把相应的乘积最小的两个数输出。
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
public class Solution {
public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
if(array.length == 0) {
return arrayList;
}
int min = 0;
int i = 0, j = array.length - 1;
while(j >= 0 && array[j] > sum) j--;
Map<Integer, Integer> map = new HashMap<>();
int [] res = new int[array.length];
while(i <= j){
map.put(array[i++], 1);
}
i = 0;
Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
while(it.hasNext()){
Map.Entry<Integer, Integer> entry = it.next();
int key = entry.getKey();
if(map.get(sum - key) != null){
res[i++] = key;
res[i++] = sum - key;
it.remove();
}
}
if(i < 1) return arrayList;
int res1 = 0, res2 = 0;
if(i >= 1){
min = res[0] * res[1];
res1 = res[0];
res2 = res[1];
}
for(j = 2; j < i; j += 2){
int num = res[j] * res[j + 1];
if(min > num){
System.out.println(min);
min = num;
res1 = res[j];
res2 = res[j + 1];
}
}
res1 = res1 < res2 ? res1 : res2;
res2 = sum - res1;
arrayList.add(res1);
arrayList.add(res2);
return arrayList;
}
}
别人的解法:
从两头夹逼,i从低到高,j从高到低,然后判断num = array[i] + array[j] 和sum的大小
1,num = array[i] + array[j] == sum 即可返回,这个即是乘积最小的
2,num = array[i] + array[j] > sum 此时证明两数之和大了,j--
3,num = array[i] + array[j] < sum 此时证明两数之和小了,i++
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
ArrayList<Integer> arrayList = new ArrayList<>();
if(array.length == 0) return arrayList;
int i = 0, j = array.length - 1;
while(i <= j){
int s = array[i] + array[j];
if(s == sum){
arrayList.add(array[i]);
arrayList.add(array[j]);
break;
}else if(s < sum){
i++;
}else{
j--;
}
}
return arrayList;
}
}

浙公网安备 33010602011771号