LeetCode1005. K 次取反後最大化的陣列和

Tomorrowland_D發表於2024-07-28

題目連結:https://leetcode.cn/problems/maximize-sum-of-array-after-k-negations/description/

題目敘述:

給你一個整數陣列 nums 和一個整數 k ,按以下方法修改該陣列:

選擇某個下標 i 並將 nums[i] 替換為 -nums[i] 。
重複這個過程恰好 k 次。可以多次選擇同一個下標 i 。

以這種方式修改陣列後,返回陣列 可能的最大和 。

示例 1:

輸入:nums = [4,2,3], k = 1
輸出:5
解釋:選擇下標 1 ,nums 變為 [4,-2,3] 。

示例 2:

輸入:nums = [3,-1,0,2], k = 3
輸出:6
解釋:選擇下標 (1, 2, 2) ,nums 變為 [3,1,0,2] 。

示例 3:

輸入:nums = [2,-3,-1,5,-4], k = 2
輸出:13
解釋:選擇下標 (1, 4) ,nums 變為 [2,3,-1,5,4] 。

提示:

1 <= nums.length <= 10^4
-100 <= nums[i] <= 100
1 <= k <= 10^4

思路:

本題思路其實比較好想了,如何可以讓陣列和最大呢?

貪心的思路,區域性最優:讓絕對值大的負數變為正數,當前數值達到最大,整體最優:整個陣列和達到最大。

區域性最優可以推出全域性最優。

那麼如果將負數都轉變為正數了,K依然大於0,此時的問題是一個有序正整數序列,如何轉變K次正負,讓 陣列和 達到最大。

我們可以對陣列進行排序,排序的規則是絕對值大的排在前面,優先對絕對值較大的負數進行取反,那麼我們就達到了區域性最大,當遍歷完陣列時,如果還有k沒有用完,

那麼我們此時就只能對最後一個元素進行取反,讓它對全域性的影響降到最低,最後我們再將變化後的陣列的元素一個一個加起來就行了!

如何實現絕對值大的在前面的排序方式?

可以採用sort函式的第三個引數,自定義排序方式,如果不會使用的話,推薦去看我的文章:sort函式中的第三個引數:自定義排序方式 https://www.cnblogs.com/Tomorrowland/p/18302319

這裡面詳細講解了sort函式的第三個引數的使用方法!

解決了排序規則的問題,其它其實都沒什麼問題了

程式碼如下:

class Solution {
public:
	// 自定義比較函式,類中的compare函式需要加上static修飾
	static bool compare(int a, int b) {
		// 按絕對值降序排序
		return abs(a) > abs(b);
	}
	int largestSumAfterKNegations(vector<int>& nums, int k) {
		sort(nums.begin(), nums.end(), compare);
		for (int i = 0; i < nums.size(); i++) {
			if (nums[i] < 0 && k>0) {
				nums[i] *= -1;
				k--;
			}
		}
		if (k % 2 == 1) nums[nums.size() - 1] *= -1;
		int sum = 0;
		for (int a : nums) {
			sum += a;
		}
		return sum;
	}
};

相關文章