在O(N)时间内求解 正数数组中 两个数相加的 最大值
一,問題描述
給定一個正數數組arr(即數組元素全是正數),找出該數組中,兩個元素相加的最大值,其中被加數的下標大于加數的下標。由加法運算的可逆性,j >i 這個條件可以去掉。
即求出: maxValue = max{arr[j]+arr[i] and j > i}?
在數組arr中沒有重復的元素情況下,若被加數的下標可以等于加數的下標,則該問題變成了尋找正數數組arr中最大值的元素了。因為 max{arr[i]} + max{arr[i]} 一定比 max{arr[i]} + arr[j] 大,其中arr[j]為數組中的任意某個元素。
而《數據結構與算法分析 Java語言描述》Mark Allen Weiss著 書中第37頁 2.28 題中并沒有指出數組arr中的元素不通重復。
?
二,求解思路
有兩種思路,一種是對數組中的每個元素,求出該元素與它后面元素的和,然后記錄下最大的。
如,對于下標為 i 的元素,for each j belongs to [i+1, arr.length)需要求出 sum=arr[i]+arr[j] 其中,i belongs to [0,arr.length) and j >=i
這算法的時間復雜度為O(N^2)
第二種思路是,先將加數初始化為下標為0的那個元素(arr[i]=arr[0]),然后,j 往后掃描,若遇到比arr[i]大的元素,則下標 i=j。也就是說,i 總是記錄比當前arr[i]更大的元素(貪心思想)。
更詳細的解釋,類似于這篇文章
代碼如下:
1 //O(N). find out the max sum of two numbers in a positive array 2 public static int maxSum(int[] arr){ 3 int i = 0; 4 int max = 0;//數組中所有的元素都是正數 5 int addValue; 6 for(int j = 1; j < arr.length; j++){ 7 addValue = arr[i] + arr[j]; 8 if(addValue > max) 9 max = addValue; 10 if(arr[j] - arr[i] > 0) 11 i = j;//記錄更大的arr[i] 12 } 13 return max; 14 }?
三,運行時間的比較
采用 這篇文章 中提到的隨機數生成算法 來隨機生成一個數組,然后比較上面兩個算法的運行時間。
機器環境如下:
OS:win7 64bit、RAM:6GB、CPU:Pentium(R)Dual-Core E5800@3.2GHz
時間比較如下:
數組大小??????? maxSum運行時間(O(N)) ????? maxSum2算法2運行時間(O(N^2))
100*100???????????? 1??????????????????????????????????????? 27
200*100???????????? 1??????????????????????????????????????? 68
300*100???????????? 2??????????????????????????????????????? 133
500*100???????????? 3??????????????????????????????????????? 359
?
此外,按照同樣的思路,也可以求解兩個數相加的最小值了,哈哈。。。。
求兩數相加的最小值,也同樣是每次貪心,貪一個較arr[i]更小的值即可,這簡直和求解兩數相減的最大值一模一樣!!!
代碼如下:
1 public static int minSum(int[] arr){ 2 int min = Integer.MAX_VALUE; 3 int i = 0; 4 int addValue; 5 for(int j = 1; j < arr.length; j++){ 6 addValue = arr[j] + arr[i]; 7 if(addValue < min) 8 min = addValue; 9 if(arr[j] - arr[i] < 0) 10 i = j; 11 } 12 return min; 13 }?
再擴展一下:還可以計算三個數相加的最大值。還是同樣的思路,當碰到比上一次運算中的 加數 更大的數時,則把該數替換掉原來加數中最小的那個加數。(三數相加,視為有三個加數。。。^-^)
再擴展一下,是不是感覺到這個問題和 求解最大子序列和 有點聯系了?? 二者都是直接跳過某些不需要“關注”的元素,并總是“貪心”出 下一個候選元素。
?
完整代碼如下:
1 public class MaxSum { 2 3 //O(N). find out the max sum of two numbers in a positive array 4 public static int maxSum(int[] arr){ 5 int i = 0; 6 int max = 0;//數組中所有的元素都是正數 7 int addValue; 8 for(int j = 1; j < arr.length; j++){ 9 addValue = arr[i] + arr[j]; 10 if(addValue > max) 11 max = addValue; 12 if(arr[j] - arr[i] > 0) 13 i = j;//記錄更大的arr[i] 14 } 15 return max; 16 } 17 18 19 public static int maxSum2(int[] arr){ 20 int max = 0; 21 int addValue; 22 for(int i = 0; i < arr.length; i++){ 23 for(int j = i+1; j < arr.length; j++){ 24 addValue = arr[j] + arr[i]; 25 if(addValue > max) 26 max = addValue; 27 } 28 } 29 return max; 30 } 31 32 public static void main(String[] args) { 33 int[] arr = C2_2_8.algorithm3(100*100*10); 34 35 long start = System.currentTimeMillis(); 36 int r = maxSum(arr); 37 long end = System.currentTimeMillis(); 38 System.out.println("maxValue=" + r + " O(N)'s time:" + (end -start)); 39 40 long start2 = System.currentTimeMillis(); 41 int r2 = maxSum2(arr); 42 long end2 = System.currentTimeMillis(); 43 System.out.println("maxValue=" + r2 + " O(N^2)'s time:" + (end2 - start2)); 44 } 45 }?
轉載于:https://www.cnblogs.com/hapjin/p/5403384.html
總結
以上是生活随笔為你收集整理的在O(N)时间内求解 正数数组中 两个数相加的 最大值的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Google Map API V3开发(
- 下一篇: 中科院分词ICTCLAS5.0_JNI