1. 程式人生 > >求給定陣列中和為s的兩個數字

求給定陣列中和為s的兩個數字

題目:輸入一個遞增排序的陣列和一個數字s,在陣列中查詢兩個數,使得它們的和正好是s。如果有多對數字的和等於s,輸出任意一對即可。

 例如:輸入陣列{1,2,4,7,11,15}和數字15.由於4+11=15,一次輸出4和11.

  思路:

(1)    如果按照開始直觀的想法就是從頭一個個的遍歷,先從1開始,然後用15-1得到14後去後面比對,如果沒有繼續從第二個數2開始,用15-2=13再到2後面的數裡找,依次類推。這種演算法的時間複雜度就是O(n的平方)。

 (2)  直觀的方法複雜度很高,是不是可以有其他優化的方法。那麼下面說下另一種思路,可以像快速排序那樣,從兩頭找。此方法複雜度為O(n)

   例如上面的例子,從兩頭找,在初始位置設定標誌位i=0(從第一個位置開始),在後端設定標誌位j=a.length-1(陣列最後一個元素位置)。然後計算兩個標誌位上的和sum(在這裡記為sum),如果sum正好等於輸入的數字s,那麼這兩個標誌位上的元素就是和為s的一對數字。如果sum小於s,那麼說明第一個標誌位可以向後移動一位,從而增大兩個標誌位上的和。同樣,如果sum大於s,第二個標誌位可以向前移動一位,從而減小sum的值。按照此規律依次查詢,如果在條件i<j(第一個標誌位要小於第二個標誌位的值)之前查詢到直接返回,如果直到此條件結束沒找到,那陣列中不存在這樣的兩個數,其和為s。

 程式碼:

import java.util.Arrays;

public class FindNumberWithSum {

	public boolean FindNumber(int[] a, int sum,int[] result) {
		boolean found=false;
		int start = 0;// 記錄陣列前端
		int end = a.length - 1;// 記錄陣列後端
		while (start < end) {
			if (a[start] + a[end] == sum) {
				result[0] = a[start];
				result[1] = a[end];
				found=true;
				break;
			} else if (a[start] + a[end] < sum) {
				start++;
			} else {
				end--;
			}

		}
		return found;
	}

	public static void main(String[] args) {
		int a[] = { -1,2, 3, 5, 8, 11,12, 13, 21, 32, 36 };
		int sum = 12;
		int[] result=new int[2];
		FindNumberWithSum object = new FindNumberWithSum();
		boolean exist = object.FindNumber(a, sum,result);
		if(exist)
		System.out.println(Arrays.toString(result));
		else
			System.out.println("不存在和為 " +sum+"的兩個數");
	}
}
輸出結果:
[-1, 13]