LeetCode 0910.最小差值 II:贪心(排序)-小数大数分界线枚举(思考过程详解)

【LetMeFly】910.最小差值 II:贪心(排序)-小数大数分界线枚举(思考过程详解)

力扣题目链接:https://leetcode.cn/problems/smallest-range-ii/

给你一个整数数组 nums,和一个整数 k

对于每个下标 i0 <= i < nums.length),将 nums[i] 变成 nums[i] + knums[i] - k

nums分数nums 中最大元素和最小元素的差值。

在更改每个下标对应的值之后,返回 nums 的最小 分数

 

    示例 1:

    输入:nums = [1], k = 0
    输出:0
    解释:分数 = max(nums) - min(nums) = 1 - 1 = 0 。
    

    示例 2:

    输入:nums = [0,10], k = 2
    输出:6
    解释:将数组变为 [2, 8] 。分数 = max(nums) - min(nums) = 8 - 2 = 6 。
    

    示例 3:

    输入:nums = [1,3,6], k = 3
    输出:3
    解释:将数组变为 [4, 6, 3] 。分数 = max(nums) - min(nums) = 6 - 3 = 3 。
    

     

    提示:

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

    解题方法:贪心(排序)

    这次每个数必须得变,考虑数组中最小的数 m m m和最大 M M M的数:

    • 如果 m m m M M M同时变大/同时变小,则差值 d i f f = M − m diff=M-m diff=Mm
    • 如果 m m m变小 M M M变大,则差值变大 d i f f = M − m + 2 k ≥ M − m diff=M-m+2k\geq M-m diff=Mm+2kMm
    • 如果 m m m变大 M M M变小,则差值为 d i f f = a b s ( ( M − k ) − ( m + k ) ) = a b s ( M − m − 2 k ) diff=abs((M-k)-(m+k))=abs(M-m-2k) diff=abs((Mk)(m+k))=abs(Mm2k)

    如果 m m m很小 M M M很大,那么那么 m m m M M M变小的话差值会变小;如果 m m m M M M相差本来不大,那么 m m m变大而 M M M变小的话 d i f f diff diff反而可能会变大。怎么办呢?

    其实不难发现,除了最小的数和最大的数,其他较小的数和较大的数也是这样的关系。

    我们可以先对数组排个序,然后枚举“小数大数的分界线”。分界线左边的数视为“小数”并且全部 + k +k +k,分界线右边的数视为“大数”并且全部 − k -k k

    在所有的方案中,差值最小的那个即为所求。

    对于一个方案,如何快速计算 d i f f diff diff呢?

    假设 n u m s [ 0 ] nums[0] nums[0] n u m s [ i ] nums[i] nums[i]每个数 + k +k +k n u m s [ i + 1 ] nums[i + 1] nums[i+1] n u m s [ n − 1 ] nums[n - 1] nums[n1]每个数 − k -k k,那么:

    数组中最大的数为 n u m s [ i ] + k nums[i] + k nums[i]+k或者 n u m s [ n − 1 ] − k nums[n - 1] - k nums[n1]k,最小的数为 n u m s [ i + 1 ] − k nums[i + 1] - k nums[i+1]k n u m s [ 0 ] + k nums[0] + k nums[0]+k

    因此 d i f f = max ⁡ ( n u m s [ i ] + k , n u m s [ l e n ( n u m s ) − 1 ] − k ) − min ⁡ ( n u m s [ i + 1 ] − k , n u m s [ 0 ] + k ) diff=\max(nums[i] + k, nums[len(nums) - 1] - k) - \min(nums[i + 1] - k, nums[0] + k) diff=max(nums[i]+k,nums[len(nums)1]k)min(nums[i+1]k,nums[0]+k)

    • 时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn),其中 n = l e n ( n u m s ) n=len(nums) n=len(nums)
    • 空间复杂度 O ( log ⁡ n ) O(\log n) O(logn),时空复杂度的开销主要来自排序

    AC代码

    C++
    class Solution {
    public:int smallestRangeII(vector<int>& nums, int k) {sort(nums.begin(), nums.end());int ans = nums.back() - nums[0];for (int i = 0; i < nums.size() - 1; i++) {  // nums[0..i]变大 nums[i+1..n-1]变小ans = min(ans, max(nums[i] + k, nums.back() - k) - min(nums[i + 1] - k, nums[0] + k));}return ans;}
    };
    
    Go
    package mainimport "slices"func smallestRangeII(nums []int, k int) int {slices.Sort(nums)ans := nums[len(nums) - 1] - nums[0]for i := 0; i < len(nums) - 1; i++ {ans = min(ans, max(nums[i] + k, nums[len(nums) - 1] - k) - min(nums[i + 1] - k, nums[0] + k))}return ans
    }
    
    Java
    import java.util.Arrays;class Solution {public int smallestRangeII(int[] nums, int k) {Arrays.sort(nums);int ans = nums[nums.length - 1] - nums[0];for (int i = 0; i < nums.length - 1; i++) {ans = Math.min(ans, Math.max(nums[i] + k, nums[nums.length - 1] - k) - Math.min(nums[i + 1] - k, nums[0] + k));}return ans;}
    }
    
    Python
    from typing import Listclass Solution:def smallestRangeII(self, nums: List[int], k: int) -> int:nums.sort()ans = nums[-1] - nums[0]for i in range(len(nums) - 1):ans = min(ans, max(nums[i] + k, nums[-1] - k) - min(nums[i + 1] - k, nums[0] + k))return ans
    

    同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

    Tisfy:https://letmefly.blog.csdn.net/article/details/143136177

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/453547.html

    如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    云网络验证系统云验证+卡密生成+多应用多用户管理

    云网络验证系统云验证&#xff0c;多样化应用管理方式&#xff0c;多种项目任你开发&#xff0c;分布式应用开关&#xff0c;让您的应用开发更简单&#xff0c;本系统借鉴于易如意API写法及思路&#xff0c;完美实现多用户多应用管理。 源码特色 1&#xff0c;对接&#xff1…

    013_django基于大数据的高血压人群分析系统2024_dcb7986h_055

    目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍&#xff1a;CodeMentor毕业设计领航者、全网关注者30W群落&#xff0c;InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者&#xff0c;博客领航之星、开发者头条/腾讯云/AW…

    MarkDownload 剪裁网页插件配置使用全流程

    前言 写在前面&#xff0c;大家有什么问题和需要可以跟我交流 需求 之前一直使用 Joplin 的剪裁网页功能&#xff0c;但是剪裁下来后不可避免的需要使用 Joplin 对剪裁下来的内容做处理&#xff0c;Joplin 用起来不是很习惯&#xff0c;所以在想可不可以用 Obsidian 来实现网…

    图的最小生成树算法--普里姆(Prim)算法和克鲁斯克尔(Kruskal)算法

    一、图的最小生成树 最小生成树&#xff08;Minimum spanning tree&#xff0c;MST&#xff09;是最小权重生成树&#xff08;Minimum weight spanning tree&#xff09;的简称&#xff0c;是一个连通加权无向图中一棵权值最小的生成树。 在一给定的无向图 G ( V , E ) G …

    探索 Jupyter 笔记本转换的无限可能:nbconvert 库的神秘面纱

    文章目录 探索 Jupyter 笔记本转换的无限可能&#xff1a;nbconvert 库的神秘面纱背景&#xff1a;为何选择 nbconvert&#xff1f;库简介&#xff1a;nbconvert 是什么&#xff1f;安装指南&#xff1a;如何安装 nbconvert&#xff1f;函数用法&#xff1a;简单函数示例应用场…

    MySQL企业常见架构与调优经验分享

    文章目录 一、选择 PerconaServer、MariaDB 还是 MYSQL二、常用的 MYSQL 调优策略三、MYSOL 常见的应用架构分享四、MYSOL 经典应用架构 观看学习课程的笔记&#xff0c;分享于此~ 课程&#xff1a;MySQL企业常见架构与调优经验分享 mysql官方优化文档 一、选择 PerconaServer、…

    全方面熟悉Maven项目管理工具(二)坐标、pom.xml文件的解读!

    1. 坐标&#xff08;核心概念&#xff09; 1.1 数学中的坐标 使用 x、y、z 三个向量作为空间的坐标系&#xff0c;可以在空间中唯一的定位到一个点 1.2 Maven 中的坐标 1.2.1 向量说明&#xff1a; 使用三个向量在 Maven的仓库 中唯一的定位到一个 jar 包 groupId&#xf…

    【某农业大学计算机网络实验报告】实验四 路由信息协议RIP

    实验目的&#xff1a; 1&#xff0e;深入了解RIP协议的特点和配置方法&#xff1a;通过此次实验&#xff0c;掌握RIP协议作为一种动态路由协议的基本工作原理&#xff0c;了解其距离向量算法的核心概念&#xff0c;以及如何在网络设备上配置RIP协议&#xff1b; 2.验证RIP协议…

    AndroidStudio实验报告——实验一、二

    目录 实验一&#xff1a; AS安装与安卓环境搭建 一、实验目标 二、实验内容 &#xff08;一&#xff09;Android Studio安装 &#xff08;二&#xff09;JDK安装与配置 &#xff08;三&#xff09;Android SDK安装与配置 三、实验结果&#xff1a;&#xff08;实…

    【Java】正则表达式详解

    目录 引言 一、基本概念 1.1 元字符 1.2 预定义字符类 1.3 边界匹配符 1.4 数量标识符 1.5 捕获与非捕获分组 二、Java中的正则表达式支持 三、正则表达式的使用示例 3.1 匹配字符串 3.2 替换字符串 3.3 分割字符串 3.4 使用Pattern和Matcher 3.5 捕获组和后向…

    局域网——Prim Kruskal

    题目 Prim &#xff08;生成一颗包含起点的最小生成树&#xff0c;所以要多次调用&#xff09; #include <bits/stdc.h>using namespace std;const int N 510; const int inf 0x3f3f3f3f;int n, m; int g[N][N], dis[N]; bool p[N], vis[N];int prim (int u) {memset(…

    分布式检测线路、精准定位故障:输电线路故障定位监测系统

    分布式检测线路、精准定位故障&#xff1a;输电线路故障定位监测系统 随着电力行业的快速发展和电网规模的不断扩大&#xff0c;输电线路作为电力传输的“生命线”&#xff0c;其安全稳定运行对于保障电力供应、促进经济社会发展具有重要意义。然而&#xff0c;输电线路通常暴…

    [云] Deploying Your First Serverless Application

    • Goal: • Hands-on lab to get started with Serverless • Agenda: • Deploying Your First Serverless Application • Assignment Introduction Create and test function in AWS Lambda • Lets create an addition function using AWS Lambda. • To create the addi…

    HCIP-HarmonyOS Application Developer 习题(十六)

    &#xff08;判断&#xff09;1、HiLink通过分布式软总线的方式连接所有设备&#xff0c;强能力设备可对弱能力设备进行设备虚拟化&#xff0c;将弱设备当做本机设备直接调用。 答案&#xff1a;错误 分析&#xff1a;HiLink 主要针对的是应用开发者与第三方设备开发者&#xf…

    100种算法【Python版】第1篇——贪心策略

    贪心是一种策略 1 策略内核1.1 基本思想1.2 策略步骤1.3 贪心算法举例说明1.3.1 活动选择问题1.3.2 01背包问题1.3.3 最优解分析 2 贪心策略的应用2.1 应用&#xff1a;计算单源最短路径2.2 应用&#xff1a;霍夫曼编码字符串 3 策略优缺点3.1 优点3.2 缺点3.3 总结 1 策略内核…

    助力语音技术发展,景联文科技提供语音数据采集服务

    语音数据采集是语音识别技术、语音合成技术以及其他语音相关应用的重要基础。采集高质量的语音数据有助于提高语音识别的准确性&#xff0c;同时也能够促进语音技术的发展。 景联文科技作为专业的数据采集标注公司&#xff0c;支持语音数据采集。可通过手机、专业麦克风阵列、专…

    快速了解Python流程控制语句基本使用

    &#x1f600;前言 在编程中&#xff0c;流程控制语句是用于控制程序执行顺序的关键部分。通过条件判断和循环机制&#xff0c;程序能够根据不同的情况选择执行特定的代码块&#xff0c;或重复执行某段代码。本文将详细介绍 Python 中常见的流程控制语句&#xff0c;包括 if、i…

    JS事件和DOM

    1. DOM 1.1 基本概念 DOM&#xff0c;全称 Document Object Model&#xff0c;即文档对象模型。它是 Web 上最常用的 API 之一&#xff0c;是加载在浏览器中的文档模型&#xff0c;可以将文档表示为节点树&#xff08;或称 DOM 树&#xff09;&#xff0c;其中每个节点代表文…

    缓存常见问题:缓存穿透、雪崩、击穿及解决方案分析

    1. 什么是缓存穿透&#xff0c;怎么解决&#xff1f; 缓存穿透是指用户请求的数据在缓存中不存在即没有命中&#xff0c;同时在数据库中也不存在&#xff0c;导致用户每次请求该数据都要去数据库中查询一遍。如果有恶意攻击者不断请求系统中不存在的数据&#xff0c;会导致短时…

    Java面试场景题(1)---如何使用redis记录上亿用户连续登陆天数

    感谢uu们的观看&#xff0c;话不多说开始~ 对于这个问题&#xff0c;我们需要先来了解一下~ 海量数据都可以用bitmap来存储&#xff0c;因为占得内存小&#xff0c;速度也很快 我大概计算了一下~ 完全够&#xff1a;String类型512M 1byte 8个bit位 8个状态 512M1024byt…