leetcode 993. 二叉树的堂兄弟节点

67 阅读1分钟

[toc] leetcode 1005. K 次取反后最大化的数组和.

题目描述

  1. 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.排序

  1. 先对数组进行排序,

  2. 反转尽可能多的负数

如果所有负数完全反转还有k(反转次数没有使用),并且为奇数,那么还要进行一次反转,

  1. 找到临界点,最小值出现的位置,就是负数反转结束的位置

  2. 计算数组的和并减去两倍的最小值(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多平台发布