贪心题解(一)

目录

K 个元素的最大和

思路

代码

 数组中最大数对和的最小值

讲解

代码

K 个元素的最大和

给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。你需要执行以下操作 恰好 k 次,最大化你的得分:

  1. 从 nums 中选择一个元素 m 。
  2. 将选中的元素 m 从数组中删除。
  3. 将新元素 m + 1 添加到数组中。
  4. 你的得分增加 m 。

请你返回执行以上操作恰好 k 次后的最大得分。

示例 1:

输入:nums = [1,2,3,4,5], k = 3
输出:18
解释:我们需要从 nums 中恰好选择 3 个元素并最大化得分。
第一次选择 5 。和为 5 ,nums = [1,2,3,4,6] 。
第二次选择 6 。和为 6 ,nums = [1,2,3,4,7] 。
第三次选择 7 。和为 5 + 6 + 7 = 18 ,nums = [1,2,3,4,8] 。
所以我们返回 18 。
18 是可以得到的最大答案。

示例 2:

输入:nums = [5,5,5], k = 2
输出:11
解释:我们需要从 nums 中恰好选择 2 个元素并最大化得分。
第一次选择 5 。和为 5 ,nums = [5,5,6] 。
第二次选择 6 。和为 6 ,nums = [5,5,7] 。
所以我们返回 11 。
11 是可以得到的最大答案。

提示:

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

思路

我感觉它题目讲得太深奥了。

其实很简单,给你一个数组,可能没排序。

然后,你要排序,当然,也可以不排,毕竟只是简单题。

情况1:不排
直接单层for循环,找出最大的,也不用什么数组了,直接累加,每次把max加给sum,就给max加1,k是多少,就进行多少次这样的操作,最后返回sum。情况1的时间复杂度是O(n)。

情况2:排序
排后,不是要最大吗?那你就把排好序的数组中最大的给它(sum),然后什么删不删除,别挺听它的,直接加1给原先最大的,所以它还是最大的。k是多少,你就取多少次,然后加1还给它。情况2的时间复杂度是O(nlogn)。

代码

import java.util.Arrays;

public class k个元素的最大和 {
    public static void main(String[] args) {
        int k=3;
        int nums[]={1,2,3,4,5};
        k个元素的最大和 kg = new k个元素的最大和();
        System.out.println(kg.maximizeSum(nums,k));
    }
    public int maximizeSum(int nums[],int k){
        int sum=0;
        //排序版:
//        Arrays.sort(nums);
//        for (int i = 0; i < k; i++) {
//            sum+=nums[nums.length-1];
//            nums[nums.length-1]+=1;
//        }
        //未排序版:
        int max=Returnmax(nums);
        for (int i = 0; i < k; i++) {
            sum+=max;
            max+=1;
        }
        return sum;
    }
    //找最大
    public int Returnmax(int nums[]){
        int max=nums[0];
        for (int i = 1; i < nums.length; i++) {
            if (max<nums[i]){
                max=nums[i];
            }
        }
        return max;
    }
}

 数组中最大数对和的最小值

一个数对 (a,b) 的 数对和 等于 a + b 。最大数对和 是一个数对数组中最大的 数对和 。

  • 比方说,如果我们有数对 (1,5) ,(2,3) 和 (4,4)最大数对和 为 max(1+5, 2+3, 4+4) = max(6, 5, 8) = 8 。

给你一个长度为 偶数 n 的数组 nums ,请你将 nums 中的元素分成 n / 2 个数对,使得:

  • nums 中每个元素 恰好 在 一个 数对中,且
  • 最大数对和 的值 最小 。

请你在最优数对划分的方案下,返回最小的 最大数对和 。

示例 1:

输入:nums = [3,5,2,3]
输出:7
解释:数组中的元素可以分为数对 (3,3) 和 (5,2) 。
最大数对和为 max(3+3, 5+2) = max(6, 7) = 7 。

示例 2:

输入:nums = [3,5,4,2,4,6]
输出:8
解释:数组中的元素可以分为数对 (3,5),(4,4) 和 (6,2) 。
最大数对和为 max(3+5, 4+4, 6+2) = max(8, 8, 8) = 8 。

提示:

  • n == nums.length
  • 2 <= n <= 105
  • n 是 偶数 。
  • 1 <= nums[i] <= 105

讲解

这道题的难度是中等,可我觉得没有,可能是贪心比较简单。

首先,我们知道nums[]数组的长度是偶数,这就节约了一次判断。

其次,由例子可以知道,有一个规律,数对的匹配是相对位置的,为什么这么说呢? 如果你对例子的数组进行排序,会发现,每次取去组为数对都是最大和最小,第二大和第二小,以此类推。

所以,我使用双指针,分别从头和尾开始,也不用进行判断,每次两根指针都走一步,这样for的时间复杂度就只有O(n/2),

但我的算法的总体时间复杂度是O(nlogn),两次快速排序反而是大户。 其实第二个存储最大数对和的数组没必要也进行快速排序,直接写一个单次循环的比大小就行了,最后返回max。

代码

import java.util.Arrays;

public class 数组中最大数对和的最小值 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
//        int nums[] = {3,5,2,3};
        int nums[] = {3,5,4,2,4,6};
        数组中最大数对和的最小值 s = new 数组中最大数对和的最小值();
        System.out.println(s.minPairSum(nums));
//        System.out.println(nums.length);
    }

    public int minPairSum(int[] nums) {
        int max = 0, j = nums.length - 1;
        Arrays.sort(nums);
        int temp[] = new int[nums.length / 2];
        for (int i = 0; i < nums.length / 2; i++) {
            temp[i] = nums[i] + nums[j--];
//            j++;
        }
        Arrays.sort(temp);
        max = temp[temp.length - 1];
        return max;
    }
}

猜你喜欢

转载自blog.csdn.net/m0_64206989/article/details/131314986