面试题 16.16. 部分排序

该问题要求找出数组中需要排序的最短子序列,使整个数组有序。使用双指针从两端向中间遍历,找到破坏顺序的元素位置。如果找到比最大值小的元素,更新右指针;如果找到比最小值大的元素,更新左指针。最后返回左右指针形成的序列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面试题 16.16. 部分排序

难度中等117收藏分享切换为英文接收动态反馈

给定一个整数数组,编写一个函数,找出索引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

题解:
    关于这道题,我姑且先这么理解:在一个数组中,有一处的连续的几个元素是无序的,只要将这个一段无序的子数组排序,就能使得整个数组有序。
    有以下几种情况:
    1、在这个数组中,只有一处无序,将这处无序的子数组排列后得到一个完整的有序数组。
    2、在这个数组中有多个无序的地方,假设有三段无序的子数组,那么从第一个无序的头部到第三个无序的尾部都需要被重新排序以适应整体的递增或递减趋势
    3、在这个数组中完全无序,那么就要从头到尾排序
    4、这已经是个有序数组,那么就直接返回[-1,-1]
    *又想到一种情况,就是,有一个具有10个元素的数组,前三个是连续递增、后七个是连续递减,那么如果按照顺序查找的话,会将后七个当做要修改重排的“无序数组”,但实际上,将前三个连续递增的改成连续递减的才符合,题目中最短子序列的要求。(又看了评论区,发现好像是默认升序。。。那就没有考虑这个的必要了(可是这样就似乎失去了找到最短序列的意义))

    双指针,从左右两边向中间遍历,因为是默认的递增顺序,所以左边的指针要找到,其右边有比自身小的位置,右边的指针要找到左边有比自身大的位置。

/**
 * @param {number[]} array
 * @return {number[]}
 */
const array = [1, 2, 4, 7, 10, 11, 7, 12, 6, 7, 16, 18, 19];
var subSort = function (array) {
  let rightt = -1;
  let leftt = -1;
  let max = Number.MIN_SAFE_INTEGER;
  let min = Number.MAX_SAFE_INTEGER;
  for (let i = 0; i < array.length; i++) {
    if (array[i] >= max) {
      max = array[i];
    } else {
      rightt = i; //如果有比max小的情况,就移动右指针
    }
    if (array[array.length - 1 - i] <= min) {
      min = array[array.length - 1 - i];
    } else {
      leftt = array.length - 1 - i;
    }
  }
  return [leftt, rightt];
};
subSort(array);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值