LeetCode.1005-K次取負數組和最大(Maximize Sum Of Array After K Negations)

這是悅樂書的第376次更新,第403篇原創

java

01 看題和準備

今天介紹的是LeetCode算法題中Easy級別的第237題(順位題號是1005)。給定一個整數數組A,咱們必須按如下方式修改數組:咱們選擇一個i並用-A[i]替換A[i],重複這個過程K次。(咱們能夠屢次選擇相同的索引。)
以這種方式修改後,返回數組可能的最大總和。例如:算法

輸入:A = [4,2,3], K = 1
輸出:5
說明:選擇索引(1,),A變爲[4,-2,3]數組

輸入:A = [3,-1,0,2], K = 3
輸出:6
說明:選擇索引(1, 2, 2),A變爲[3,1,0,2]數據結構

輸入:A = [2,-3,-1,5,-4], K = 2
輸出:13
說明:選擇索引(1, 4),A變爲[2,3,-1,5,4]優化

注意code

  • 1 <= A.length <= 10000排序

  • 1 <= K <= 10000索引

  • -100 <= A[i] <= 100

    io

02 第一種解法

題目的意思是將A中的數進行取反(正變負,負變正)K次,能夠重複對一個元素取反,最後求A中元素總和的最大值。取反能夠分爲兩種狀況:class

A中都是正數的時候,好比{1,2,4,6},若是K是偶數,那麼能夠不用進行取反操做,由於負負得正;若是K是奇數,則只須要對最小的數取反一次便可。

A中有正數也有負數的時候,好比{-4,-3,-1,2,5},此時對負數元素進行取反操做,直到當前元素大於0或者K次轉換已用完,此時針對K中剩餘的轉換次數,又能夠細分爲兩種狀況:

(1)K中剩餘的轉換次數爲偶數,即A中元素全是正數,依據負負得正,不用再進行額外的轉換了。

(2)K中剩餘的轉換次數爲奇數,即還須要再將某個元素轉換一次,而爲了元素總和最大,須要比較當前元素(正數)和前一個元素(負數)的絕對值大小,對較小的元素進行取反。

最後使用一個for循環,計算A中全部元素總和。

public int largestSumAfterKNegations(int[] A, int K) {
    int sum = 0;
    Arrays.sort(A);
    if (A[0] >= 0) {
        if (K%2 != 0) {
            A[0] = -A[0];
        }
    } else {
        int i = 0;
        while (A[i] <= 0 && K > 0) {
            A[i] = -A[i];
            i++;
            K--;
        }
        // K中剩餘有轉換次數且爲奇數
        if (K > 0 && K%2 != 0) {
            // 取較小的元素進行取反
            if (Math.abs(A[i]) < Math.abs(A[i-1])) {
                A[i] = -A[i];
            } else {
                A[i-1] = -A[i-1];
            }
        }
    }
    // 求和
    for (int num : A) {
        sum += num;
    }
    return sum;
}


03 第二種解法

思路和第一種解法相似,只是在處理K中剩餘的轉換次數爲奇數這個問題上作了下優化,在第一種解法中,咱們是比較最後一次轉換的負數和它前一個正數的大小,換種角度理解,這兩個數已經處於全部元素中的底部了,就像一個U型曲線的底同樣,而爲了元素總和最大,須要將較小的值取反,即找出全部元素中的最小值便可。

先對A排序,利用循環,將前面的負數進行轉換,順便計算元素總和並找出最小元素,若是A中負數已所有轉換完成(A中已不包含負數),且K中還有剩餘的轉換次數,而且剩餘的轉換次數爲奇數,則將最小的正數減去兩次,由於sum是所有元素的和,且所有元素都是正數,對最小的元素取反後變爲負數,則sum須要減兩次最小元素。例如{1,2,3}的和爲6,對1取反後變爲{-1,2,3},其和爲4

public int largestSumAfterKNegations2(int[] A, int K) {
    Arrays.sort(A);
    int sum = 0, min = Integer.MAX_VALUE;
    for (int num : A) {
        if (num <= 0 && K > 0) {
            num = -num;
            K--;
        }
        sum += num;
        min = Math.min(min, num);
    }
    // K中有剩餘轉換次數且爲奇數
    if (K > 0 && K%2 != 0) {
        // 減去2次最小值
        sum -= min*2;
    }
    return sum;
}


04 小結

算法專題目前已連續日更超過七個月,算法題文章242+篇,公衆號對話框回覆【數據結構與算法】、【算法】、【數據結構】中的任一關鍵詞,獲取系列文章合集。

以上就是所有內容,若是你們有什麼好的解法思路、建議或者其餘問題,能夠下方留言交流,點贊、留言、轉發就是對我最大的回報和支持!

相關文章
相關標籤/搜索