LeetCode每日1题--1005. K 次取反后最大化的数组和

72 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第33天,点击查看活动详情

前言

算法的重要性不言而喻!区分度高!

现在学习的门槛低了,只有能上网每个人都可以学编程!培训班6个月就可以培养出来能干活的人,你怎么从这些人中脱颖而出?没错!就是学算法,学一些底层和基础的东西。

说的功利点是为了竞争,卷死对手。真心话说就是能提高自己的基础能力,为技术可持续发展做好充分的准备!!!

提前入门学习书籍:CPrimerPlus、大话数据结构

image-20220705103735001

刷题网站

代码随想录 (programmercarl.com)

leetcode

我是按照代码随想录提供的刷题顺序进行刷题的,大家也可以去刷leetcode最热200道,都可以

刷题嘛,最重要的就是坚持了!!!

画图软件

OneNote

这个要经常用,遇见不懂的流程的话就拿它画一画!

笔记软件

Typoral

题目

leetcode.cn/problems/ma…

image.png

解析

本题的思路其实还是比较好想的到的,如何才能得到数组的最大和呢?

那就每一次都选数组最大的数加一块,所以局部就是让绝对值大的负数变为正数,当前数值达到最大,整体最优:整个数组和达到最大。

进而局部最优可以推出全局最优。这就是思路!

那还有一个问题,题目说的是k次取反,如果k次后已经满足局部最优了咋办?这里又涉及到一个贪心,都是正数了那我就选最小的正数变为负数

从而可以看出这简单的一道题就用到了两个贪心

所以整理下我们的解题思路:

  • 数组从大到小排序(绝对值大小)
  • 从前向后进行遍历,遇到负数就把它搞为正数,同时k--
  • 同时判断k是否>0,如果是那就反复的去转变数组中数值最小的数,直到k<=0
  • 求和

完整代码

对于这种题我们能做的就是多写多练

class Solution {
    public int largestSumAfterKNegations(int[] nums, int K) {
    	// 将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
	nums = IntStream.of(nums)
		     .boxed()
		     .sorted((o1, o2) -> Math.abs(o2) - Math.abs(o1))
		     .mapToInt(Integer::intValue).toArray();
	int len = nums.length;	    
	for (int i = 0; i < len; i++) {
	    //从前向后遍历,遇到负数将其变为正数,同时K--
	    if (nums[i] < 0 && K > 0) {
	    	nums[i] = -nums[i];
	    	K--;
	    }
	}
	// 如果K还大于0,那么反复转变数值最小的元素,将K用完

	if (K % 2 == 1) nums[len - 1] = -nums[len - 1];
	return Arrays.stream(nums).sum();

    }
}

后期我们会更新DP的写法!