數對之差的最大值 子陣列的最大和

2021-06-28 02:51:14 字數 3091 閱讀 7456

問題1: 在陣列中,數字減去他的右邊的數字得到乙個數對之差,求所有數對之差的最大值。 例如陣列中,數對之差的最大值是11,是16減去5的結果。

問題2:給定乙個含有n 個元素的數列,元素有正有負,找出和最小的一組相鄰的書,既給定a[n],是的a[i]+a[i+1]+...+a[j]的和最小。

先看第一道題目:

如果從頭遍歷,遍歷到某乙個位置,從這個位置開始遍歷到陣列結束,看此元素的數對只差的最帶值,然後更行當前的數對之差的最大值,o(n^2)的事件複雜度。

解法二:轉化成求解子陣列的最大和問題

接下來再介紹一種比較巧妙的解法。如果輸入乙個長度為

n的陣列

numbers

,我們先構建乙個長度為

n-1的輔助陣列

diff

,並且diff[i]

等於numbers[i]-numbers[i+1]

(0<=i)。如果我們從陣列

diff

中的第i

個數字一直累加到第

j個數字(

j > i

),也就是

diff[i] + diff[i+1] + … + diff[j] = (numbers[i]-numbers[i+1]) + (numbers[i + 1]-numbers[i+2]) + ... + (numbers[j] – numbers[j + 1]) = numbers[i] – numbers[j + 1]。

分析到這裡,我們發現原始陣列中最大的數對之差(即numbers[i] – numbers[j + 1])其實是輔助陣列diff中最大的連續子陣列之和。

int maxdiff_solution2(int numbers,unsigned length)

if(numbers == null || length < 2)

return 0;

int* diff = new

int[length - 1];

for(int i = 1; i < length; ++i)

diff[i - 1] = numbers[i - 1] - numbers[i];

int currentsum = 0;

int greatestsum = 0x80000000;

for(int i = 0; i < length - 1; ++i)

if(currentsum <= 0)

currentsum = diff[i];

else

currentsum += diff[i];

if(currentsum > greatestsum)

greatestsum = currentsum;

delete diff;

return greatestsum;

解法三:動態規劃法

既然我們可以把求最大的數對之差轉換成求子陣列的最大和,而子陣列的最大和可以通過動態規劃求解,那我們是不是可以通過動態規劃直接求解呢?下面我們試著用動態規劃法直接求數對之差的最大值。

我們定義diff[i]是以陣列中第i個數字為減數的所有數對之差的最大值。也就是說對於任意h(h < i),diff[i]≥number[h]-number[i]。diff[i](0≤i)的最大值就是整個陣列最大的數對之差。

假設我們已經求得了diff[i],我們該怎麼求得diff[i+1]呢?對於diff[i],肯定存在乙個h(h < i),滿足number[h]減去number[i]之差是最大的,也就是number[h]應該是number[i]之前的所有數字的最大值。當我們求diff[i+1]的時候,我們需要找到第i+1個數字之前的最大值。第i+1個數字之前的最大值有兩種可能:這個最大值可能是第i個數字之前的最大值,也有可能這個最大值就是第i個數字。第i+1個數字之前的最大值肯定是這兩者的較大者。我們只要拿第i+1個數字之前的最大值減去number[i+1],就得到了diff[i+1]。

int maxdiff_solution3(int numbers,unsigned length)

if(numbers == null || length < 2)

return 0;

int max = numbers[0];

int maxdiff =  max - numbers[1];

for(int i = 2; i < length; ++i)

if(numbers[i-1] > max)

max = numbers[i-1];

int currentdiff = max - numbers[i];

if(currentdiff > maxdiff)

maxdiff = currentdiff;

return maxdiff;

在上述**中,max表示第i個數字之前的最大值,而currentdiff表示diff[i](0≤i),diff[i]的最大值就是**中maxdiff。轉換思維非常的重要。

上述是解決第乙個問題的方法,至於第二個問題,求出連續陣列的最小和。如果我們設定乙個輔助陣列,是的這個陣列為b[n]

b[0] = a[0], b[1] = a[0]+a[1] b[2] = a[0]+a[1]+a[2]  b[3] = a[0]+a[1]+a[2]+a[3]  b[i] = a[0]+a[1]+...+a[i]  b[n] = a[0]+a[1]+.....+a[n]

那麼 a[i]+a[i+1]+......+a[j]  = b[j]-b[i-1]  也就是說求得乙個連續序列的最小和就相當於求得b[n]陣列中的數對之差的最小值。

這麼一來就相當於第乙個問題了,其中s是輔助陣列

j = 1; i = 0; max = 0;

for (i=1; is[i] ? i : max;

}

這個演算法的思想是: s[i] 肯定是 s[j] 之前最大的數,s[j] 也是 s[i] 之後最小的數,那麼保留到目前為止最大的數 s[max],用當前數 s[i] 去減它(肯定是小於 s[i] - s[i] 的),看它是否小於 s[j] - s[i],如果是的話,那麼 s[i] -s[max] 就是到 i 為止最小的差值對。掃瞄一遍 s[n] 就能得到結果,o(n)!

這裡只不過是使用了最大元素的下標!

數對之差的最大值

題目 在陣列中,數字減去它右邊的數字得到乙個數對之差。求所有數對之差的最大值。例如在陣列中,數對之差的最大值是11,是16減去5的結果。static int maxdiff int arr if arr.length 2 arr null return 0 int max arr 0 intmaxd...

數對之差的最大值

題目 在陣列中,數字減去它右邊的數字得到乙個數對之差。求所有數對之差的最大值。例如在陣列中,數對之差的最大值是11,是16減去5的結果。分析 看到這個題目,很多人的第一反應是找到這個陣列的最大值和最小值,然後覺得最大值減去最小值就是最終的結果。這種思路忽略了題目中很重要的一點 數對之差是乙個數字減去...

數對之差的最大值 演算法

題目 在陣列中,數字減去它右邊的數字得到乙個數對之差。求所有數對之差的最大值。例如在陣列中,數對之差的最大值是11,是16減去5的結果。分析 看到這個題目,很多人的第一反應是找到這個陣列的最大值和最小值,然後覺得最大值減去最小值就是最終的結果。這種思路忽略了題目中很重要的一點 數對之差是乙個數字減去...