求給定陣列中和為s的兩個數字
阿新 • • 發佈:2019-02-02
題目:輸入一個遞增排序的陣列和一個數字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]