java数组题(5)

(1):

思路:

1.首先要对数组nums排序,这样两数之间的差距最小。

2.题目要求我们通过最多 k 次递增操作,使数组中某个元素的频数(出现次数)最大化。经过上面的排序,最大数组也就是在整个数组里的某一截。使用滑动窗口

3.初始化两个指针**leftright,分别表示滑动窗口的左右边界**,假设我们获得了一截数组是我们想要的,怎么证明呢?判断条件是什么?

  1. 要最大可能频数,先定义一个maxF来表示最高频元素的最大可能频数 。可以通过Math.max来获得最大频数。

5.做一个假设,在窗口里的数字都变成最高元素(也就是right指针所在)。那么n个元素*最高元素=MaxSum,这个最大总和减去实际n个元素的总和的值(MaxSum-Sum=x) ,要是大于k就说明在这个滑动窗口里,数据太多,k达不到最高频元素的最大可能频数。左指针++。同时更新 sum,直到 sum 不大于 k 更新 maxF

6.返回 maxF

代码:

java 复制代码
import java.util.Arrays;

public class Solution {
    public int maxFrequency(int[] nums, int k) {
        Arrays.sort(nums);
        int left = 0;
        long sum = 0;
        int maxFreq = 0;
        
        for (int right = 0; right < nums.length; right++) {
            sum += nums[right];
            while ((long) nums[right] * (right - left + 1) - sum > k) {
                sum -= nums[left];
                left++;
            }
            maxFreq = Math.max(maxFreq, right - left + 1);
        }
        
        return maxFreq;
    }
}

代码解释:

  1. 排序数组:首先对数组进行排序,以便后续使用滑动窗口。
  2. 初始化变量
    • left:滑动窗口的左边界
    • sum:窗口内所有元素的和(使用long避免整数溢出)
    • maxF:记录最大频数
  3. 滑动窗口遍历
    • 右指针right从 0 开始遍历数组
    • 每次将当前元素加入窗口,并更新窗口和sum
    • 检查当前窗口是否满足条件:nums[right] * (right - left + 1) - sum <= k
      • 如果不满足,则缩小窗口左边界left,并更新窗口和sum
    • 更新最大频数maxF
  4. 返回结果:遍历结束后返回最大频数。

复杂度分析:

  • 时间复杂度:O (n log n)(排序) + O (n)(滑动窗口遍历)= O (n log n)
  • 空间复杂度:O (1)(仅使用常数额外空间

(2):

思路:

我们需要通过重新排列数组元素并减小它们的值,使得数组的第一个元素为 1,且相邻元素的差的绝对值不超过 1,同时最大化数组中的最大值。关键在于构造一个从 1 开始的递增序列,每个元素尽可能比前一个大 1,因为这样可以得到最大的可能值

  1. 排序数组:首先将数组排序,以便后续处理。
  2. 贪心构造递增序列:从 1 开始,依次尝试构造下一个数(当前数 + 1),只要数组中存在至少一个元素大于等于当前需要构造的数,就可以使用该元素来构造,并继续构造下一个更大的数。

代码:

java 复制代码
import java.util.Arrays;

class Solution {
    public int maximumElementAfterDecrementingAndRearranging(int[] arr) {
        Arrays.sort(arr);
        int required = 1; // 需要构造的下一个数,初始为1(第一个元素必须是1)
        for (int x : arr) {
            if (x >= required) {
                required++; // 可以构造当前required,接下来构造required+1
            }
        }
        return required - 1; // 最大构造到required-1,因为最后一次递增了required
    }
}

代码解释

  1. 排序数组 :使用Arrays.sort(arr)对数组进行升序排序,以便从小到大处理每个元素。
  2. 初始化变量required表示当前需要构造的下一个数,初始为 1,因为数组的第一个元素必须是 1。
  3. 遍历数组 :对于每个元素x,如果x大于等于当前需要构造的数required,则说明可以使用该元素来构造required,并将required加 1,尝试构造下一个更大的数(required + 1)。
  4. 返回结果 :最终required - 1即为能够构造的最大数,因为每次成功构造一个数后required会递增,最后一次递增后required比最大数大 1。

这种方法通过贪心策略,每次尽可能构造更大的数,确保了构造的序列是连续递增的,从而最大化了数组中的最大值。时间复杂度主要由排序决定,为 O (n log n),空间复杂度为 O (1)(不考虑排序的栈空间)。

相关推荐
爱笑的源码基地22 分钟前
一款全开源的信创云PACS影像云平台解决方案,支持多模态医学影像处理(CT/MR/DR/超声/病理等)
java·源码·国产化·pacs·云影像·区域pacs
可编程芯片开发29 分钟前
基于CPS-SPWM链式STATCOM系统在电压不平衡环境下控制策略的simulink建模与仿真
算法
我命由我1234539 分钟前
Android 开发问题:ClickableSpan 的点击事件没有生效
java·java-ee·android studio·android jetpack·android-studio·android runtime
万亿少女的梦1681 小时前
基于Python的高考志愿填报辅助系统设计与实现
java·spring boot·python·mysql·vue
Jerry1 小时前
LeetCode 202. 快乐数
算法
微信开发api-视频号协议1 小时前
企业微信外部群开发自动化实践过程
java·前端·微信·自动化·企业微信·ipad
hans汉斯1 小时前
基于改进交叉熵损失函数与Transformer的心电信号高风险分类研究
功能测试·深度学习·算法·yolo·目标检测·分类·transformer
Jerry1 小时前
LeetCode 349. 两个数组的交集
算法
犀利豆2 小时前
#AI in Harness(一)
java·ai编程
极***涯2 小时前
深度拆解:多源BFS路径重构难题——跳出单层遍历误区,搞定高阶最短路径全量解
java·重构·宽度优先