[路飞]_leetcode-面试题 16.16-部分排序

简介: leetcode-面试题 16.16-部分排序

网络异常,图片无法展示
|


「这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战


[题目地址][B站地址]


给定一个整数数组,编写一个函数,找出索引mn,只要将索引区间[m,n]的元素排好序,整个数组就是有序的。注意:n-m尽量最小,也就是说,找出符合条件的最短序列。函数返回值为[m,n],若不存在这样的mn(例如整个数组是有序的),请返回[-1,-1]


示例:


输入: [1,2,4,7,10,11,7,12,6,7,16,18,19]
输出: [3,9]
复制代码


提示:


  • 0 <= len(array) <= 1000000


解题思路


本题可以想到最简单直接的方法拷贝原数组并排序,然后从左向右对比元素是否相同,第一个不同的位置即为 m,同理从右向左对比元素是否相同,第一个不同的位置即为 n


最后判断 [m,n] 是否合法,如果合法,返回 [m,n],否则返回 [-1,-1


这样的方法可以解决问题,但是因为进行了一次排序和两次查找,以 sort 进行排序为例,排序时间复杂度 O(nlogn),查找两个边界的时间复杂度为 O(n),总体时间复杂度 O(n+nlogn)。有的小伙伴可能会说可以利用 计数排序 和 基数排序 将排序时间复杂度降低为 O(n),但是提交后效率依然不高,是因为本题我们可以不对原数组排序查找两个边界下标。


我们可以首先从左往右找右边界,初始化 n = 0,记录已处理区间中的最大值,如果在后续遍历过程中找到一个值比最大值小,说明此时出现了前大后小的情况,说明该位置是需要排序的,更新 n 等于当前下标,这样一次扫描后就确定了右边界 n。 同理可以从右往左找左边界,初始化 m = len-1len 为输入数组长度),记录已处理区间中的最小值, 如果找到一个值比最小值大,说明此时出现了前大后小的情况,说明该位置是需要排序的,则更新左边界 m 为该下标,这样一次扫描就确定了左边界 m


如此我们通过两次遍历数组就确定了 mn,最后判断 [m,n] 是否合法,如果合法,返回 [m,n],否则返回 [-1,-1


动画演示


网络异常,图片无法展示
|


代码实现


var subSort = function (array) {
  // 获取输入数组长度
  const len = array.length
  // 如果数组长度小于2,无法找到合法区间,返回 [-1,-1]
  if (len < 2) return [-1, -1]
  // 初始化右边界及最大值
  let n = 0,
    max = array[0],
    // 初始化左边界及最小值
    m = len - 1,
    min = array[len - 1]
  // 从左向右确定右边界
  for (let i = 1; i < len; i++) {
    if (array[i] >= max) max = array[i]
    else n = i
  }
  // 从右向左确定左边界
  for (let i = len - 2; i >= 0; i--) {
    if (array[i] <= min) min = array[i]
    else m = i
  }
  // 如果区间合法,返回区间,否则返回 [-1,-1]
  return m >= n ? [-1, -1] : [m, n]
}
复制代码


至此我们就完成了 leetcode-面试题 16.16-部分排序


如有任何问题或建议,欢迎留言讨论!👏🏻👏🏻👏🏻

相关文章
|
2天前
|
Java
【LeetCode力扣】面试题 17.14. 最小K个数(top-k问题)
【LeetCode力扣】面试题 17.14. 最小K个数(top-k问题)
7 1
|
2天前
|
算法
【刷题】 leetcode 面试题 08.05.递归乘法
递归算法是一种在计算机科学和数学中广泛应用的解决问题的方法,其基本思想是利用问题的自我相似性,即将一个大问题分解为一个或多个相同或相似的小问题来解决。递归算法的核心在于函数(或过程)能够直接或间接地调用自身来求解问题的不同部分,直到达到基本情况(也称为基础案例或终止条件),这时可以直接得出答案而不必再进行递归调用。 ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog
15 4
【刷题】 leetcode 面试题 08.05.递归乘法
|
2天前
|
存储 算法 安全
【刷题】 leetcode 面试题 01.06 字符串压缩
来看效果: 非常好!!!过啦!!!
22 5
|
1月前
|
C++ 索引
【力扣经典面试题】14. 最长公共前缀
【力扣经典面试题】14. 最长公共前缀
|
1月前
|
C++
【力扣经典面试题】58. 最后一个单词的长度
【力扣经典面试题】58. 最后一个单词的长度
|
1月前
|
算法 Java
【力扣经典面试题】12. 整数转罗马数字
【力扣经典面试题】12. 整数转罗马数字
|
1月前
|
索引
[经典力扣面试题]135. 分发糖果
[经典力扣面试题]135. 分发糖果
|
1月前
|
算法 C++ 索引
【力扣经典面试题】238. 除自身以外数组的乘积
【力扣经典面试题】238. 除自身以外数组的乘积
|
1月前
|
算法 索引
【力扣经典面试题】274. H 指数
【力扣经典面试题】274. H 指数
|
1月前
|
算法 测试技术 索引
【力扣经典面试题】45. 跳跃游戏 II
【力扣经典面试题】45. 跳跃游戏 II

热门文章

最新文章