1. 程式人生 > >設計一個演算法找到陣列中兩個元素相加等於指定數的所有組合

設計一個演算法找到陣列中兩個元素相加等於指定數的所有組合

找出數組裡面任意兩個數相加等於某個k值(假設陣列中存在這樣的兩個數) ,這是以前在36氪二面問的一個演算法題。

思路1:窮舉法,兩層for迴圈

思路2:可以用hash表來儲存陣列中的元素,這樣我們取得一個數後,去判斷sum - val 在不在陣列中,如果在陣列中,則找到了一對二元組,它們的和為sum,該演算法的缺點就是需要用到一個hash表,增加了空間複雜度。

思路3:同樣是基於查詢,我們可以先將陣列排序,然後依次取一個數後,在陣列中用二分查詢,查詢sum -val是否存在,如果存在,則找到了一對二元組,它們的和為sum,該方法與上面的方法相比,雖然不用實現一個hash表,也沒不需要過多的空間,但是時間多了很多。排序需要O(nLogn),二分查詢需要(Logn),查詢n次,所以時間複雜度為O(nLogn)。

思路4:該方法基於第2種思路,但是進行了優化,在時間複雜度和空間複雜度是一種折中,但是演算法的簡單直觀、易於理解。首先將陣列排序,然後用兩個指向陣列的指標,一個從前往後掃描,一個從後往前掃描,記為first和last,如果 fist + last < sum 則將fist向前移動,如果fist + last > sum,則last向後移動。

思路4

public static void main(String args[]) {
        int[] data = {1, 5, 9, -1, 4, 6, -2, 3, -8};
        Arrays.sort(data);
        printPairSums1(data, data.length, 8);
    }

    private static void printPairSums(int data[], int size, int sum) {
        int first = 0;
        int last = size - 1;
        int s = 0;
        while (first < last) {
            s = data[first] + data[last];
            if (s == sum) {
                System.out.println("-------"  + data[first] + " + " + data[last] + " = " + sum);
                first++;
                last--;
            } else if (s < sum) {
                first++;
            } else {
                last--;
            }
        }
    }