這是悅樂書的第376次更新,第403篇原創
java
今天介紹的是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
題目的意思是將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; }
思路和第一種解法相似,只是在處理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; }
算法專題目前已連續日更超過七個月,算法題文章242+篇,公衆號對話框回覆【數據結構與算法】、【算法】、【數據結構】中的任一關鍵詞,獲取系列文章合集。
以上就是所有內容,若是你們有什麼好的解法思路、建議或者其餘問題,能夠下方留言交流,點贊、留言、轉發就是對我最大的回報和支持!