一,問題描述
給定乙個正數陣列arr(即陣列元素全是正數),找出該陣列中,兩個元素相減的最大值,其中被減數的下標不小於減數的下標。
即求出: maxvalue = max
二,求解思路
下面採用兩種不同的演算法來求解,第一種演算法的時間複雜度為o(n),第二種演算法的時間複雜度為o(n^2)。
演算法一思路如下:(初始時減數為arr[0],然後演算法不斷記錄比當前減數更小的減數)
maxvalue初始化為0,因為當 i==j 時,arr[j] - arr[i] = 0,故 maxvalue的值不可能為負數。
因此將下標 i 初始化為0,j 從下標1處開始向後掃瞄,並計算sub = arr[j]-arr[i]
若sub大於maxvalue,則更新maxvalue的值。
否則,若sub小於0,意味著找到乙個新的陣列元素,該陣列元素比 arr[i]的值要小,則更新下標 i.
為什麼這樣可以?
因為:當計算 sub = arr[j]-arr[i]時,arr[i]越小,則得到的sub越大。而下標 i 不斷標記更小的減數,後面的元素arr[j]與 更小的減數相減才能得到更大的差值。
比如,下圖所示陣列:
arr[0]=18,當j=2時,max=arr[2]-arr[0]=8。當遍歷到arr[3]=12時,由於12小於18,故把下標 i 由 0 更新為 3。不需要」關注「下標為1和2的這兩個元素。因為,
若在 j>3 後面有元素使得 arr[j]-arr[1] 或者 arr[j]-arr[2]>maxvalue,則該arr[j]-arr[0]一定比 arr[j]-arr[1]更大,因為arr[1]和 arr[2]都比arr[0]大。
同理:也不需要關注元素值為12 和 元素值為10之間的元素,因為,若後面某個元素減去某個 「12 到 10之間的元素(16、18、22)」比maxvalue大,那麼它減去12一定更大。
這樣,下標 i 記錄的總是下乙個比 arr[i] 更小的值(這有點類似於貪心演算法的味道,每次總是貪比當前值更小的乙個值),而不是如演算法2中那樣依次遍歷陣列中的每個元素。
**如下:
1演算法二://演算法複雜度o(n). 找出陣列arr中兩個數相減的最大值
2public
static
int maxvalueofsubtraction(int
arr)
13return
max;
14 }
就是乙個很普通的方法。求出 陣列中所有下標大的元素減去下標小的元素,找出其中的最大值即可。**如下:
1乙個錯誤的解法://o(n^2) 找出陣列arr中兩個數相減的最大值
2public
static
int maxvaluesub(int
arr)11}
12return
max;
13 }
由於題目中要求的是 被減數的下標要大於減數的下標,故下面解法是錯誤的:
依次掃瞄陣列中的每個元素,找出陣列元素中的最大值和最小值。最大值減去最小值 即為兩個元素相減的最大值。
錯誤的原因是:最大值元素的下標 可能 比 最小值元素的下標要小。
錯誤解法**如下:
1三,執行時間的比較public
static
int maxvaluesub3(int
arr)
11else
if(arr[i]
16 system.out.println("indexm" + indexm + " indexm:" +indexm);
17return max -min;
18 }
採用 這篇文章 中提到的隨機數生成演算法 來隨機生成乙個陣列,然後比較上面兩個演算法的執行時間。
機器環境如下:
os:win7 64bit、ram:6gb、cpu:pentium(r)dual-core [email protected]
時間比較如下:
陣列大小 演算法1執行時間 演算法2執行時間
100*100 1 61
200*100 3 158
400*100 2 568
500*100 2 878
100*100*10 4 3451
整個**如下:
1/*2* given an array, find out the max value of two numbers's distraction.
3* max under the condition of j>=i4*/
5public
class
maxvalue
19return
max;
20}
2122
//o(n^2) 找出陣列arr中兩個數相減的最大值
23public
static
int maxvaluesub(int
arr)32}
33return
max;34}
3536
37public
static
void
main(string args)
50 }
Python實現 兩個陣列的交集 的兩種方法
給定兩個陣列,寫乙個方法輸出它們的交集 example 1 input nums1 1,2,2,1 nums2 2,2 output 2,2 example 2 input nums1 4,9,5 nums2 9,4,9,8,4 output 4,9 注意 輸出結果中每乙個元素出現的次數和兩個陣列中...
575A兩種方法刪除區間和01兩個陣列
刪除區間 初始化位置。include intmain num 0 while scanf d d l,m l sum num l 1 end begin 1 記錄每組資料剩餘的樹 for i 0 i return0 01兩個陣列 memcoy0.include include 有乙個長度為整數l 1...
兩種方法求解逆序對
逆序對定義 對於乙個包含n個非負整數的陣列a 1.n 如果有i j,且a i a j 則稱 a i a j 為陣列a中的乙個逆序對。常見的兩種方法求解逆序對 1.窮舉法 暴力求解 時間複雜度o n 2 2.歸併法,時間複雜度o nlogn 窮舉法 對於乙個給定的序列,依次從左往右取每乙個元素,從該元...