【劍指offer】面試題57(1):和為S的數字
阿新 • • 發佈:2019-01-05
題目
輸入一個遞增排序的陣列和一個數字S,在陣列中查詢兩個數,是的他們的和正好是S,如果有多對數字的和等於S,輸出兩個數的乘積最小的。
ps: 對應每個測試案例,輸出兩個數,小的先輸出。
思路
看程式碼前的註釋
程式碼
/**
* 題目:
* 輸入一個遞增排序的陣列和一個數字S,在陣列中查詢兩個數,使得他們的和正好是S,
* 如果有多對數字的和等於S,輸出兩個數的乘積最小的。
* 對應每個測試案例,輸出兩個數,小的先輸出。
*
* 思路:
* 充分利用陣列已排序的特點,
* 將第一個指標指向陣列最小的元素(頭),將第二個指標指向陣列最大的元素(末尾)
* 若此時兩個元素的和等於S,則這是我們要的答案
* 如果此時兩個元素的和小於S,則將第一個指標指向下一個元素
* 如果此時兩個元素的和大於S,則將第二個指標指向前一個元素
*
* 題目要求如果有多對符合的數字,則輸出兩數乘積最小的
* 設兩數的和為2m,則其中一個數字為m-a,另外一個數字為m+a
* (m+a)(m-a) = m² - a²
* 所以當a越大,乘積越小
*
* 即本題中,兩個陣列下標差越大時,乘積越小,即第一對符合的元素就是我們要的答案
*
* @author peige
*/
public class _57_01_TwoNumbersWithSum {
public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
if(array == null || array.length < 2)
return new ArrayList<>();
int low = 0;
int high = array.length - 1;
while(low < high) {
if (array[low] + array[high] > sum)
--high;
else if(array[low] + array[high] < sum)
++low;
else
return new ArrayList<>(Arrays.asList(array[low], array[high]));
}
return new ArrayList<>();
}
}
測試
public class _57_01_Test {
public static void main(String[] args) {
test1();
test2();
test3();
}
private static void test1() {
int[] array = new int[] {1,2,3,4,4,5,6,7,8,9};
_57_01_TwoNumbersWithSum tnws = new _57_01_TwoNumbersWithSum();
// 1,9
System.out.println(tnws.FindNumbersWithSum(array, 10));
// 1,8
System.out.println(tnws.FindNumbersWithSum(array, 9));
// 1,5
System.out.println(tnws.FindNumbersWithSum(array, 6));
}
private static void test2() {
int[] array = new int[] {1,2};
_57_01_TwoNumbersWithSum t = new _57_01_TwoNumbersWithSum();
System.out.println(t.FindNumbersWithSum(array, 3));
}
/**
* 極端測試
* 1.陣列為null
* 2.陣列長度小於2
* 3.數組裡沒有符合的元素
*/
private static void test3() {
_57_01_TwoNumbersWithSum t = new _57_01_TwoNumbersWithSum();
// null
System.out.println(t.FindNumbersWithSum(null, 1));
// null
System.out.println(t.FindNumbersWithSum(new int[1], 1));
// null
System.out.println(t.FindNumbersWithSum(new int[] {1,2,3,4}, 8));
}
}