很有意思的一道数学推理题目, 剪枝以后解法也很简洁。
初看貌似需要把每个数跟其他数作比较。但排序以后可以发现情况大大简化:
对于任一对元素a[i] < a[j], a[i] - k和a[j] + k 的情况可以排除, 因为会产生比原值更大的差, 所以对于原有数组的最小值min最大值max, (min - k, max + k)的情况可以排除。剩下的三种情况, (min - k, max - k), (min + k, max + k) 和 (min + k, max - k),后两种等价于原值max - min, 我们可以把初始最大差值设为max - min, 确保最终结果不会比这个平凡值更坏。
对于最后一种情况(min + k, max - k), 需要继续分情况讨论。
方便起见,我们可以把所有元素都预先-k, 然后从最小元素开始,尝试依次把各元素+2*k.
我们可以证明,如果选择a[i] + 2 * k,那么之前任一元素a[j] (0 <= j < i)加上 2 * k,都不会使结果更坏。证明见此:
B = [A[0] + 2K, ...,A[i-1]+2K, A[i] + 0, A[i+1] +2K, ..., A[j]+2K, ..., A[j+1]+0, A[n-1]+0]
B' = [A[0] + 2K, ...,A[i-1]+2K, A[i] + 2K, A[i+1] +2K, ..., A[j]+2K, ..., A[j+1]+0, A[n-1]+0]
A[i]+2K is between A[i-1] + 2K and A[i+1] +2K, so it must stand in the range of B.
B' is not worse than B, it can be easily generalized to multiple elements added by 0 between the ones added by 2K.
于是当我们考虑a[i] + 2 * k时,可以假设之前的元素都已经加上了2 * k。
当前最大差值取决于:
1) 当前数列最小值:
可能为a[i+1]
a[i+1],...a[0]+2*k...a[n-1]...
或a[0]+2*k
a[0]+2*k..., a[i+1],...a[n-1]...
2) 以及当前数列最大值:
可能为a[i]+2*k
...a[n-1]...a[i]+2*k
或者a[n-1]
...a[i]+2*k...a[n-1]

因此我们只需遍历所有元素,计算当前元素加上2*k的以后的数组的最大差值,取其中的最小值即可。

public:
int smallestRangeII(vector<int>& a, int k) {
size_t len = a.size();
if(len <= ) return ;
sort(a.begin(), a.end());
int front = a.front(), back = a.back(), d = back - front, start = front + * k;
if( k >= d) return d;
int ans = d;
for(size_t i = ; i < len - ; i++){
int lo = min(start, a[i + ]), hi = max(a[i] + * k, back);
ans = min(ans, hi - lo);
}
return ans;
}

参考:https://zhanghuimeng.github.io/post/leetcode-910-smallest-range-ii/

LeetCode 910. Smallest Range II的更多相关文章

  1. [LeetCode] 910. Smallest Range II 最小区间之二

    Given an array A of integers, for each integer A[i] we need to choose either x = -K or x = K, and ad ...

  2. 【LeetCode】910. Smallest Range II 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  3. 【leetcode】910. Smallest Range II

    题目如下: 解题思路:我的思路是先找出最大值.对于数组中任意一个元素A[i]来说,如果A[i] + K 是B中的最大值,那么意味着从A[i+1]开始的元素都要减去K,即如果有A[i] + K > ...

  4. 910. Smallest Range II

    Given an array A of integers, for each integer A[i] we need to choose either x = -K or x = K, and ad ...

  5. [LeetCode] 908. Smallest Range I 最小区间

    Given an array A of integers, for each integer A[i] we may choose any x with -K <= x <= K, and ...

  6. [LeetCode] 632. Smallest Range Covering Elements from K Lists 覆盖K个列表元素的最小区间

    You have k lists of sorted integers in ascending order. Find the smallest range that includes at lea ...

  7. [leetcode]632. Smallest Range最小范围

    You have k lists of sorted integers in ascending order. Find the smallest range that includes at lea ...

  8. [Swift]LeetCode910. 最小差值 II | Smallest Range II

    Given an array A of integers, for each integer A[i] we need to choose either x = -K or x = K, and ad ...

  9. LeetCode 908 Smallest Range I 解题报告

    题目要求 Given an array A of integers, for each integer A[i] we may choose any x with -K <= x <= K ...

随机推荐

  1. ASP.NET Core 上传多文件 超简单教程

    示例源码下载地址 https://qcloud.coding.net/api/project/3915794/files/4463836/download 项目地址 https://dev.tence ...

  2. JavaScript 变量声明提升

    JavaScript 变量声明提升 一.变量提升的部分只是变量的声明,赋值语句和可执行的代码逻辑还保持在原地不动 二.在基本的语句(或者说代码块)中(比如:if语句.for语句.while语句.swi ...

  3. 没有什么问题是sudo rm -rf /* 解决不了的

    没有什么问题是sudo rm -rf /* 解决不了的. . . . . . . 如果有的话,赶紧跑.

  4. iOS js

    [webView stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"idNumber\" ...

  5. ZooKeeper学习之路 (六)ZooKeeper API的简单使用(二)级联删除与创建

    编程思维训练 1.级联查看某节点下所有节点及节点值 2.删除一个节点,不管有有没有任何子节点 3.级联创建任意节点 4.清空子节点 ZKTest.java public class ZKTest { ...

  6. expand_dims函数

    >>> x = np.array([1,2]) >>> x.shape (2,) >>> y = np.expand_dims(x, axis=0 ...

  7. Oracle编辑数据时提示:这些查询结果不可更新,请使用ROWI或者SELECT……FOR UPDATE获得可更新结果

    我们在对Oracle数据库进行操作时,有时会在查询完结果后想要对其中的某些数据进行操作,当我们点击编辑(一个锁标志)是,会提示我们上述问题中的错误:这些查询结果不可更新,请使用ROWI或者SELECT ...

  8. ZCMU 2177 Lucky Numbers (easy)

    传送门: http://acm.zcmu.edu.cn/JudgeOnline/problem.php?id=2177 2177: Lucky Numbers (easy) 时间限制: 2 Sec   ...

  9. 基于MySql数据库的单表与多表联合查询

    这里以学生 班级 身份证 以及课程为例 1,启动MySql数据库  开启服务 2.1.0新建一张班级表 备注:CHARSET = UTF8 (指定编码格式为utf8 防止中文乱码) /*班级表*/ C ...

  10. spring学习笔记---数据库事务并发与锁详解

    多事务运行并发问题 在实际应用中,往往是一台(或多台)服务器向无数客户程序提供服务,当服务器查询数据库获取数据时,如果没有采用必要的隔离机制,可能会存在数据库事务的并发问题,下面是一些常见的并发问题分 ...