目录
K 个元素的最大和
给你一个下标从 0 开始的整数数组 nums
和一个整数 k
。你需要执行以下操作 恰好 k
次,最大化你的得分:
- 从
nums
中选择一个元素m
。 - 将选中的元素
m
从数组中删除。 - 将新元素
m + 1
添加到数组中。 - 你的得分增加
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;
}
}