当前位置: 首页 > news >正文

【练习】【贪心】力扣1005. K 次取反后最大化的数组和

题目

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] 。

来源:力扣1005. K 次取反后最大化的数组和


思路(注意事项)

思路一:建立小根堆,每次修改堆顶(即最小值)。
思路二:贪心(条件排序)


纯代码1

class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        priority_queue<int, vector<int>, greater<int>> q;

        for (int i = 0; i < nums.size() ; i ++) q.push(nums[i]);

        int ans = 0;
        for (int i = 0 ;i < k; i ++)
        {
            int t = - q.top();
            q.pop();
            q.push(t);
        }
        while(!q.empty()) ans += q.top(), q.pop();
        return ans;
    }
};

题解1(加注释)

class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        // 定义一个最小堆(优先队列),用于存储数组中的元素
        priority_queue<int, vector<int>, greater<int>> q;

        // 将数组中的所有元素放入最小堆
        for (int i = 0; i < nums.size(); i++) q.push(nums[i]);

        // ans 用于存储最终的累加和
        int ans = 0;

        // 进行 k 次取反操作
        for (int i = 0; i < k; i++) {
            // 取出堆顶元素(当前最小的元素)
            int t = -q.top();
            // 将堆顶元素弹出
            q.pop();
            // 将取反后的元素重新放入堆中
            q.push(t);
        }

        // 计算堆中所有元素的和
        while (!q.empty()) {
            ans += q.top(); // 取出堆顶元素并累加到 ans
            q.pop();        // 弹出堆顶元素
        }

        // 返回最终的累加和
        return ans;
    }
};

纯代码2

class Solution {
static bool cmp (int a, int b)
{
    return abs(a) > abs(b);
}
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort (nums.begin(), nums.end(), cmp);
        int ans = 0;
        for (int i = 0; i < nums.size() && k > 0; i ++)
            if (nums[i] < 0) nums[i] = - nums[i], k --;
        
        if (k % 2 == 1) nums[nums.size() - 1] *= -1;
        for (auto i : nums) ans += i;
        return ans;
    }
};

题解2(加注释)

#include <vector>
#include <algorithm>
#include <cmath>

class Solution {
    // 自定义比较函数,用于 std::sort 排序
    // 该函数的作用是按照绝对值从大到小对元素进行排序
    static bool cmp (int a, int b)
    {
        // 返回绝对值大的元素排在前面
        return abs(a) > abs(b);
    }
public:
    // 该函数用于计算经过 k 次取反操作后数组元素的最大和
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        // 使用自定义的 cmp 函数对数组进行排序,使得绝对值大的元素排在前面
        sort (nums.begin(), nums.end(), cmp);
        
        // 用于存储最终的数组元素和
        int ans = 0;
        
        // 遍历数组,优先将绝对值大的负数取反
        for (int i = 0; i < nums.size() && k > 0; i ++) {
            // 如果当前元素是负数,将其取反,并将 k 减 1
            if (nums[i] < 0) {
                nums[i] = - nums[i];
                k --;
            }
        }
        
        // 如果 k 还有剩余且为奇数,说明还需要进行一次取反操作
        // 此时对绝对值最小的元素进行取反,因为前面已经按绝对值从大到小排序,所以最后一个元素绝对值最小
        if (k % 2 == 1) {
            nums[nums.size() - 1] *= -1;
        }
        
        // 遍历数组,计算所有元素的和
        for (auto i : nums) {
            ans += i;
        }
        
        // 返回最终的和
        return ans;
    }
};

相关文章:

  • 可以用于promise面试的例子--其1
  • 基于单片机的机床切屑运输系统设计
  • cv2.solvePnP 报错 求相机位姿
  • 车载电源管理新标杆NCV8460ADR2G 在汽车电子负载开关中的应用
  • 删除idea recent projects 记录
  • springboot项目部署脚本
  • c++11新特性 chrono库
  • yolov8 目标追踪 (源码 +效果图)
  • JS中let和var变量区别
  • LeetCode刷题 -- 29. 两数相除
  • 8、HTTP/1.0和HTTP/1.1的区别【高频】
  • 测试金蝶云的OpenAPI
  • Python面试(八股)
  • 如何管理路由器
  • 做表格用什么软件?VeryReport让数据管理更高效!
  • 如果使用MODBUS通用类进行通信
  • 【无标题】Ubuntu22.04编译视觉十四讲slambook2 ch4时fmt库的报错
  • 【Nodejs】用pm2管理nodejs服务
  • PyCharm中通过命令行执行`pip`命令下载到哪里了:虚拟环境目录下
  • 3 算法1-3 回文质数
  • 天水做网站的/网络营销方式有哪几种
  • 通州网站制作/吉林seo推广
  • 深圳网站建设的基/搜索引擎是网站吗
  • 专做品牌的网站/在线咨询 1 网站宣传
  • 做动态网站 和数据库交互/软文发稿网站
  • 点图片跳到网站怎么做/百度一下百度下载