zoukankan      html  css  js  c++  java
  • [LeetCode] 1005. Maximize Sum Of Array After K Negations

    Given an integer array nums and an integer k, modify the array in the following way:

    • choose an index i and replace nums[i] with -nums[i].

    You should apply this process exactly k times. You may choose the same index i multiple times.

    Return the largest possible sum of the array after modifying it in this way.

    Example 1:

    Input: nums = [4,2,3], k = 1
    Output: 5
    Explanation: Choose index 1 and nums becomes [4,-2,3].
    

    Example 2:

    Input: nums = [3,-1,0,2], k = 3
    Output: 6
    Explanation: Choose indices (1, 2, 2) and nums becomes [3,1,0,2].
    

    Example 3:

    Input: nums = [2,-3,-1,5,-4], k = 2
    Output: 13
    Explanation: Choose indices (1, 4) and nums becomes [2,3,-1,5,4].

    Constraints:

    • 1 <= nums.length <= 104
    • -100 <= nums[i] <= 100
    • 1 <= k <= 104

    K 次取反后最大化的数组和。

    给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:

    选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。
    重复这个过程恰好 k 次。可以多次选择同一个下标 i 。

    以这种方式修改数组后,返回数组 可能的最大和 。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/maximize-sum-of-array-after-k-negations
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    这道题我给出两种做法,一种会利用到优先队列 priority queue,另一种是排序,背后的思路其实差不多。因为题目定义是请你取反 K 次使得取反过后数组的和最大,那么我们肯定是需要把最小的数字找出来,如果是负数就最好了。找到负数之后如果能把 K 消耗完的话,就是最优解;如果不能,则需要再去找所有数字里最小的,再对其取反。

    涉及到具体做法的时候,如果是 priority queue 的话,这里我们创建一个最小堆,这样最小的元素在堆顶。只要 K 没有用完,我们就对堆顶元素不停取反。

    时间O(nlogn)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int largestSumAfterKNegations(int[] nums, int k) {
     3         PriorityQueue<Integer> pq = new PriorityQueue<>();
     4         for (int num : nums) {
     5             pq.offer(num);
     6         }
     7         while (k > 0) {
     8             pq.offer(-pq.poll());
     9             k--;
    10         }
    11         
    12         int sum = 0;
    13         while (!pq.isEmpty()) {
    14             sum += pq.poll();
    15         }
    16         return sum;
    17     }
    18 }

    如果是排序的做法的话,需要排序两次。第一次排序之后我们可能能把所有本来就是负数的处理掉,如果此时 K 还未用完,我们需要对数组再次排序,再把其中较小的元素取反。

    时间O(nlogn)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int largestSumAfterKNegations(int[] nums, int k) {
     3         Arrays.sort(nums);
     4         int count = 0;
     5         if (nums[0] < 0) {
     6             for (int i = 0; i < nums.length && count < k; i++) {
     7                 if (nums[i] < 0) {
     8                     nums[i] = -nums[i];
     9                     count++;
    10                 } else {
    11                     break;
    12                 }
    13             }
    14         }
    15 
    16         if (count < k) {
    17             Arrays.sort(nums);
    18             int res = (k - count) % 2;
    19             if (res > 0) {
    20                 nums[0] = -nums[0];
    21             }
    22         }
    23 
    24         int sum = 0;
    25         for (int num : nums) {
    26             sum += num;
    27         }
    28         return sum;
    29     }
    30 }

    LeetCode 题目总结

  • 相关阅读:
    May 1 2017 Week 18 Monday
    April 30 2017 Week 18 Sunday
    April 29 2017 Week 17 Saturday
    April 28 2017 Week 17 Friday
    April 27 2017 Week 17 Thursday
    April 26 2017 Week 17 Wednesday
    【2017-07-04】Qt信号与槽深入理解之一:信号与槽的连接方式
    April 25 2017 Week 17 Tuesday
    April 24 2017 Week 17 Monday
    为什么丑陋的UI界面却能创造良好的用户体验?
  • 原文地址:https://www.cnblogs.com/cnoodle/p/15640744.html
Copyright © 2011-2022 走看看