当前位置: 首页 > news >正文

排序题目:三次操作后最大值与最小值的最小差

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法一
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法二
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:三次操作后最大值与最小值的最小差

出处:1509. 三次操作后最大值与最小值的最小差

难度

5 级

题目描述

要求

给定一个数组 nums \texttt{nums} nums,每次操作可以选择 nums \texttt{nums} nums 中的任意一个元素并将其改成任意值。

返回三次操作后 nums \texttt{nums} nums 中最大值与最小值的差的最小值。

示例

示例 1:

输入: nums = [5,3,2,4] \texttt{nums = [5,3,2,4]} nums = [5,3,2,4]
输出: 0 \texttt{0} 0
解释:将数组 [5,3,2,4] \texttt{[5,3,2,4]} [5,3,2,4] 变成 [2,2,2,2] \texttt{[2,2,2,2]} [2,2,2,2]。最大值与最小值的差为 2 − 2 = 0 \texttt{2} - \texttt{2} = \texttt{0} 22=0

示例 2:

输入: nums = [1,5,0,10,14] \texttt{nums = [1,5,0,10,14]} nums = [1,5,0,10,14]
输出: 1 \texttt{1} 1
解释:将数组 [1,5,0,10,14] \texttt{[1,5,0,10,14]} [1,5,0,10,14] 变成 [1,1,0,1,1] \texttt{[1,1,0,1,1]} [1,1,0,1,1]。最大值与最小值的差为 1 − 0 = 1 \texttt{1} - \texttt{0} = \texttt{1} 10=1

数据范围

  • 1 ≤ nums.length ≤ 10 5 \texttt{1} \le \texttt{nums.length} \le \texttt{10}^\texttt{5} 1nums.length105
  • -10 9 ≤ nums[i] ≤ 10 9 \texttt{-10}^\texttt{9} \le \texttt{nums[i]} \le \texttt{10}^\texttt{9} -109nums[i]109

解法一

思路和算法

如果数组的长度不大于 4 4 4,则经过最多三次操作之后一定可以使数组中的所有元素相等,此时最小的差是 0 0 0

如果数组的长度大于 4 4 4,则将数组升序排序之后,对最小的 x x x 个数和最大的 y y y 个数操作可以使得差最小,其中 x x x y y y 都是非负整数, x + y = 3 x + y = 3 x+y=3

n n n 表示数组 nums \textit{nums} nums 的长度,用 i i i j j j 分别表示有序数组中的第 x + 1 x + 1 x+1 小的数和第 y + 1 y + 1 y+1 大的数所在下标,则有 i = x i = x i=x j = n − y − 1 j = n - y - 1 j=ny1,根据 x + y = 3 x + y = 3 x+y=3 可得 j − i = n − 4 j - i = n - 4 ji=n4。将最小的 x x x 个元素改成 nums [ i ] \textit{nums}[i] nums[i] 并将最大的 y y y 个元素改成 nums [ j ] \textit{nums}[j] nums[j],则操作之后的最大值是 nums [ j ] \textit{nums}[j] nums[j],最小值是 nums [ i ] \textit{nums}[i] nums[i],最大值与最小值的差是 nums [ j ] − nums [ i ] \textit{nums}[j] - \textit{nums}[i] nums[j]nums[i]

如果操作的元素不是最小的 x x x 个元素和最大的 y y y 个元素,则操作之后一定存在小于等于 nums [ i ] \textit{nums}[i] nums[i] 的值或大于等于 nums [ j ] \textit{nums}[j] nums[j] 的值,最大值与最小值的差一定不会小于 nums [ j ] − nums [ i ] \textit{nums}[j] - \textit{nums}[i] nums[j]nums[i]。因此为了使最大值与最小值的差最小,应该操作最小的 x x x 个元素和最大的 y y y 个元素。

遍历所有满足 0 ≤ i , j < n 0 \le i, j < n 0i,j<n j − i = n − 4 j - i = n - 4 ji=n4 的下标对 ( i , j ) (i, j) (i,j),计算每个下标对的 nums [ j ] − nums [ i ] \textit{nums}[j] - \textit{nums}[i] nums[j]nums[i],其中的最小差值即为三次操作后 nums \textit{nums} nums 中最大值与最小值的差的最小值。

代码

class Solution {public int minDifference(int[] nums) {int n = nums.length;if (n <= 4) {return 0;}Arrays.sort(nums);int minDiff = nums[n - 1] - nums[0];for (int i = 0, j = n - 4; j < n; i++, j++) {minDiff = Math.min(minDiff, nums[j] - nums[i]);}return minDiff;}
}

复杂度分析

  • 时间复杂度: O ( n log ⁡ n ) O(n \log n) O(nlogn),其中 n n n 是数组 nums \textit{nums} nums 的长度。排序需要 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的时间,排序后需要遍历数组中的四个下标对,遍历的时间是 O ( 1 ) O(1) O(1),时间复杂度是 O ( n log ⁡ n ) O(n \log n) O(nlogn)

  • 空间复杂度: O ( log ⁡ n ) O(\log n) O(logn),其中 n n n 是数组 nums \textit{nums} nums 的长度。排序需要 O ( log ⁡ n ) O(\log n) O(logn) 的递归调用栈空间。

解法二

思路和算法

根据解法一可知,只需要维护数组 nums \textit{nums} nums 中最大的四个元素与最小的四个元素,即可得到最大值与最小值的最小差值。因此,可以在不排序的情况下遍历数组得到最大的四个元素与最小的四个元素,然后计算最大值与最小值的最小差值。

维护两个长度为 4 4 4 的数组 maxVals \textit{maxVals} maxVals minVals \textit{minVals} minVals 分别用于存储最大的四个元素与最小的四个元素,初始时 maxVals \textit{maxVals} maxVals 的元素值都是 − ∞ -\infty minVals \textit{minVals} minVals 的元素值都是 + ∞ +\infty +。遍历数组 nums \textit{nums} nums 的过程中更新 maxVals \textit{maxVals} maxVals minVals \textit{minVals} minVals,并保持 maxVals \textit{maxVals} maxVals 单调递减和 minVals \textit{minVals} minVals 单调递增。

遍历数组 nums \textit{nums} nums 结束之后,对于 0 ≤ i < 4 0 \le i < 4 0i<4 的每个下标 i i i 计算 maxVals [ i ] − minVals [ 3 − i ] \textit{maxVals}[i] - \textit{minVals}[3 - i] maxVals[i]minVals[3i],其中的最小值即为三次操作后 nums \textit{nums} nums 中最大值与最小值的最小差值。

代码

class Solution {public int minDifference(int[] nums) {int n = nums.length;if (n <= 4) {return 0;}int[] maxVals = new int[4];int[] minVals = new int[4];Arrays.fill(maxVals, Integer.MIN_VALUE);Arrays.fill(minVals, Integer.MAX_VALUE);for (int num : nums) {int maxIndex = 0;while (maxIndex < 4 && num <= maxVals[maxIndex]) {maxIndex++;}if (maxIndex < 4) {for (int i = 2; i >= maxIndex; i--) {maxVals[i + 1] = maxVals[i];}maxVals[maxIndex] = num;}int minIndex = 0;while (minIndex < 4 && num >= minVals[minIndex]) {minIndex++;}if (minIndex < 4) {for (int i = 2; i >= minIndex; i--) {minVals[i + 1] = minVals[i];}minVals[minIndex] = num;}}int minDiff = Integer.MAX_VALUE;for (int i = 0; i < 4; i++) {minDiff = Math.min(minDiff, maxVals[i] - minVals[3 - i]);}return minDiff;}
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums 的长度。遍历数组需要 O ( n ) O(n) O(n) 的时间,由于只需要维护四个最大元素和四个最小元素,因此每个元素更新最大与最小元素的时间都是 O ( 1 ) O(1) O(1)

  • 空间复杂度: O ( 1 ) O(1) O(1)。由于只需要维护四个最大元素和四个最小元素,因此空间复杂度是 O ( 1 ) O(1) O(1)


http://www.mrgr.cn/news/30261.html

相关文章:

  • 智能车镜头组入门(四)元素识别
  • 图片翻译器,分享四款直接翻译图片的软件!
  • SourceTree保姆级教程3:(分支创建 及 合并)
  • 深入探讨 JVM 内存泄漏与溢出:定位与解决方案
  • VirtualBox7.1.0 安装 Ubuntu22.04.5 虚拟机
  • 【机器学习】OpenCV高级图像处理
  • 睢宁自闭症寄宿学校:培养特殊孩子的无限潜能
  • 【科技论文写作与发表】论文分类
  • springboot通过tomcat部署项目(包含jar、war两种方式,迄今为止全网最详细!2024更新..建议收藏,教学!万字长文!)
  • 当 PC 端和移动端共用一个域名时,避免 CDN 缓存页面混乱(nginx)
  • C++:类和对象全解
  • 海康威视摄像机和录像机的监控与回放
  • 【安当产品应用案例100集】017-助力软件服务商高效集成多因素认证
  • MySql调优(三)Query SQL优化(2)explain优化
  • 小学教师计算机培训教案
  • 【Linux】动静态库
  • python怎么打开文件对话框
  • web自动化学习笔记
  • [leetcode] 69. x 的平方根
  • Hive自定义函数——简单使用