【LeetCode】1005. K 次取反后最大化的数组和(简单)——代码随想录算法训练营Day33

本文主要是介绍【LeetCode】1005. K 次取反后最大化的数组和(简单)——代码随想录算法训练营Day33,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接:1005. 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

文章讲解:代码随想录

视频讲解:贪心算法,这不就是常识?还能叫贪心?LeetCode:1005.K次取反后最大化的数组和_哔哩哔哩_bilibili

题解1:暴力法

思路:先翻转负数,再翻转0,然后翻转正数,需要处理多种细节。

/*** @param {number[]} nums* @param {number} k* @return {number}*/
var largestSumAfterKNegations = function(nums, k) {nums.sort((a, b) => a - b);let sum = 0;// 翻转负数let i = 0;while (i < nums.length && nums[i] < 0 && k--) {sum += -nums[i++];}// 消耗多余翻转次数if (k > 0 && i < nums.length) {if (nums[i] === 0) {// 翻转0k = 0;} else {// 翻转正数if (i === 0) {sum -= nums[i];} else {if (k % 2 === 1) {if (nums[i] <= -nums[i - 1]) {sum -= nums[i];} else {sum += 2 * nums[i - 1] + nums[i];}} else {sum += nums[i];}}}i++;} else if (k > 0) {if (k % 2 === 1) {sum += 2 * nums[i - 1];}}while (i < nums.length) {sum += nums[i++];}return sum;
};

分析:时间复杂度为 O(nlogn),空间复杂度为 O(1)。

题解2:贪心算法

思路:先对数组按绝对值进行降序排列,进行两次贪心策略,先翻转负数,如果次数还有剩余,此时数组中全是非负数,然后翻转最小的非负数。

/*** @param {number[]} nums* @param {number} k* @return {number}*/
var largestSumAfterKNegations = function(nums, k) {// 将数组按绝对值降序排序nums.sort((a, b) => Math.abs(b) - Math.abs(a));// 翻转负数nums = nums.map((num) => k > 0 && num < 0 && k-- && -num || num);// 翻转正数if (k % 2 === 1) {nums[nums.length - 1] = -nums[nums.length - 1];}return nums.reduce((a, b) => a + b);
};

分析:时间复杂度为 O(nlogn),空间复杂度为 O(1)。

收获

贪心算法的套路并不固定,有些题目需要使用两次贪心策略,要注意以局部最优到全局最优的角度思考问题。

这篇关于【LeetCode】1005. K 次取反后最大化的数组和(简单)——代码随想录算法训练营Day33的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/715821

相关文章

Java中有什么工具可以进行代码反编译详解

《Java中有什么工具可以进行代码反编译详解》:本文主要介绍Java中有什么工具可以进行代码反编译的相关资,料,包括JD-GUI、CFR、Procyon、Fernflower、Javap、Byte... 目录1.JD-GUI2.CFR3.Procyon Decompiler4.Fernflower5.Jav

javaScript在表单提交时获取表单数据的示例代码

《javaScript在表单提交时获取表单数据的示例代码》本文介绍了五种在JavaScript中获取表单数据的方法:使用FormData对象、手动提取表单数据、使用querySelector获取单个字... 方法 1:使用 FormData 对象FormData 是一个方便的内置对象,用于获取表单中的键值

Vue ElementUI中Upload组件批量上传的实现代码

《VueElementUI中Upload组件批量上传的实现代码》ElementUI中Upload组件批量上传通过获取upload组件的DOM、文件、上传地址和数据,封装uploadFiles方法,使... ElementUI中Upload组件如何批量上传首先就是upload组件 <el-upl

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

C++一个数组赋值给另一个数组方式

《C++一个数组赋值给另一个数组方式》文章介绍了三种在C++中将一个数组赋值给另一个数组的方法:使用循环逐个元素赋值、使用标准库函数std::copy或std::memcpy以及使用标准库容器,每种方... 目录C++一个数组赋值给另一个数组循环遍历赋值使用标准库中的函数 std::copy 或 std::

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没