1. 程式人生 > >劍指Offer - 和為S的兩個字(Java實現)

劍指Offer - 和為S的兩個字(Java實現)

題目描述:

輸入一個遞增排序的陣列和一個數字S,在陣列中查詢兩個數,使得他們的和正好是S,如果有多對數字的和等於S,輸出兩個數的乘積最小的。

輸出描述:

對應每個測試案例,輸出兩個數,小的先輸出。

思路分析:
假設a<b,則ab>(a-1)(b+1)。這說明,從左側開始先找到的數肯定是乘積最小的數。所以開始的思路就是從左側開始遍歷,直到找出滿足條件的兩個數放入集合中。但是這樣的話,遞增排序的陣列的這一個條件就基本上沒用上,而且時間複雜度是大於O(N)的。所以根據題意以及分析可知,可以採用頭尾雙指標的方法,若兩數的和大於sum,則將右指標左移一位再進行判斷,若兩數的和小於sum,則將左指標右移一位再進行判斷,邊界條件是左指標小於右指標。

方法1:暴力遍歷法

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> FindNumbersWithSum(int[] array,int sum) {
        int p1 = 0;
        int p2 = 1;
        ArrayList<Integer> list = new ArrayList<>();
        if(array == null || array.length < 2){
            return list;
        }
        while(array[p1] + array[p2] <= sum ){
            for(int i = p1,j = p2; j < array.length; j++){
                if(array[i]+array[j]==sum){
                    list.add(array[i]);
                    list.add(array[j]);
                    return list;
                }
                if(array[i]+array[j] > sum){
                    break;
                }
            }
            p1++;
            p2 = p1+1;
        }
        return list;
    }
}

方法2:頭尾雙指標的方法

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 i = 0;
        int j = array.length-1;
        while(i < j){
            if(array[i]+array[j]==sum){
                list.add(array[i]);
                list.add(array[j]);
                return list;
            }
            else if(array[i]+array[j] > sum){
                j--;
            }
            else{
                i++;
            }
        }
        return list;
    }
}