[toc] leetcode 1005. K 次取反后最大化的数组和.
题目描述
- K 次取反后最大化的数组和
给你一个整数数组 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 <= 104 -100 <= nums[i] <= 100 1 <= k <= 104
解题思路
法1
方法1.排序
-
先对数组进行排序,
-
反转尽可能多的负数
如果所有负数完全反转还有k(反转次数没有使用),并且为奇数,那么还要进行一次反转,
-
找到临界点,最小值出现的位置,就是负数反转结束的位置
-
计算数组的和并减去两倍的最小值(k反转完负数还是奇数的时候才减)
- 时间复杂度(O(nlogn))
- 空间复杂度(O(1))
执行结果
法1
func addar(nums []int)(r int){//数组和
for _, v := range nums {
r+=v
}
return
}
func min(x,y int)int{//较小的数字
if x>y {
return y
}
return x
}
func largestSumAfterKNegations(nums []int, k int) int {
sort.Ints(nums)
// 最大的将负数变为正数
i := 0
for ; k > 0 &&i<len(nums); i++ {
if nums[i] >= 0{
break
}
k--
nums[i] = -nums[i]
if i==len(nums)-1{break}
}
//临界点
if k%2==1 {//还需要进行一次反转
//临界位置的较小值进行反转
if i==0 {
return addar(nums)-2*nums[0]
}
return addar(nums)-2*min(nums[i],nums[i-1])
}
return addar(nums)
}
执行结果: 通过 显示详情 查看示例代码 添加备注
执行用时: 4 ms , 在所有 Go 提交中击败了 86.47% 的用户 内存消耗: 2.4 MB , 在所有 Go 提交中击败了 99.41% 的用户 通过测试用例: 81 / 81 炫耀一下:
本文由mdnice多平台发布