前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >新手程序员靠刷题真的能进大厂吗?

新手程序员靠刷题真的能进大厂吗?

作者头像
五分钟学算法
发布2022-05-27 16:06:11
2720
发布2022-05-27 16:06:11
举报
文章被收录于专栏:五分钟学算法五分钟学算法

大家好,我是吴师兄。

大家最近还在努力的刷题吗?

今天分享面试题 16:部分排序

一、题目描述

给定一个整数数组,编写一个函数,找出索引 m 和 n ,只要将索引区间 [m,n] 的元素排好序,整个数组就是有序的。(默认是递增有序数组)

注意:n - m 尽量最小,也就是说,找出符合条件的最短序列。

函数返回值为 [m,n] ,若不存在这样的 m 和 n(例如整个数组是有序的),请返回 [-1,-1] 。

二、题目解析

对于元素 a[i] 来说,如果它左边存在大于 a[i] 的元素,那么 a[i] 是一定要加入到被排序的序列内

如果它右边存在小于 a[i] 的元素,那么a[i]` 也要加入到被排序的序列内

所以,我们的目的很明确。

1、寻找最靠右的那个数,即它的左边存在大于它的数

2、寻找最靠左的那个数,即它的右边存在小于它的数

这两个数之间就是要排序的区间

最靠右的数具备以下特征:

1、它的左边存在大于它的数

2、它的右边数都比它更大

3、相对于多个符合 1、2 要求的数,它是最靠右的

同样的,最靠左的数具备以下特征:

1、它的右边存在小于它的数

2、它的左边数都比它更小

3、相对于多个符合 1、2 要求的数,它是最靠左的

三、参考代码

代码语言:javascript
复制
// 登录 AlgoMooc 官网获取更多算法图解
// https://www.algomooc.com
// 作者:程序员吴师兄
// 代码有看不懂的地方一定要私聊咨询吴师兄呀
// 部分排序 (面试题 16):https://leetcode-cn.com/problems/sub-sort-lcci/ 
class Solution {
    public int[] subSort(int[] array) {

        // 如果数组为空、或者数组没有元素、或者数组只有一个元素,找不出符合要求的序列,根据题目要求返回 [-1,-1]
        if(array == null || array.length == 0 || array.length == 1) return new int[]{-1,-1};

        // 正常来说,整个数组是递增有序的,比如 1 3 5 9 10 这种
        // 如果某个元素的左边存在比它更大的元素,比如  1 10 5  
        // 5 这个元素的左边存在 10 这个元素比它更大,一定 5 要参与到排序里去的

        // 如果某个元素的右边存在比它更小的元素,比如  1 10 5  
        // 10 这个元素的右边存在 5 这个元素比它更小,所以 10 一定要参与到排序里去的

        // 所以我们只需要寻找最靠右的那个数(满足左边存在大于它的数)
        // 和最靠左的那个数(满足右边存在小于它的数)
        // 那么这两个数之间就是要排序的区间了

        // 第一次遍历是从尾到头进行遍历,目的是为了找出最靠左的那个数,即满足右边存在小于它的数

        // 一开始默认最右边的数为最小值
        int min = array[array.length - 1];

        // 默认找不到的情况下 m 为 -1
        int m = -1;

        // 从尾到头进行遍历,直到遍历到数组的开始位置
        for( int j = array.length - 2 ; j >= 0 ; j-- ){
            // 获取当前遍历的元素值
            int cur = array[j] ;
            // 如果此时当前的元素值小于等于最小值,需要更新最小值
            if(cur <= min){
                // 更新最小值
                min = cur;
            }else{
                // 如果当前元素大于了最小值,由于我们是从尾到头进行遍历,说明当前元素的右边存在小于它的数,这个元素需要加入到排序的区间
                // 比如  10 9 7
                // 最小值是 7 ,而 9 大于 7,所以 9 需要加入到排序的区间
                // 因此更新 m 的值为 j,说明此时遍历的那些元素中 j 是最靠左的那个数
                m = j;
            }
        }


        // 第二次遍历是从尾到头进行遍历,目的是为了找出最靠右的那个数,即满足左边存在大于它的数

        // 一开始默认最左边的数为最大值
        int max = array[0];
        
        // 默认找不到的情况下 n 为 -1
        int n = -1;

        // 从头进行遍历,直到遍历到数组的结束位置
        for( int i = 1 ; i < array.length ; i++ ){
            // 获取当前遍历的元素值
            int cur = array[i] ;
            // 如果此时当前的元素值大于等于最大值,需要更新最大值
            if(cur >= max){
                // 更新最大值
                max = array[i];
            }else{
                // 如果当前元素小于了最大值,由于我们是从头到尾进行遍历,说明当前元素的左边存在大于它的数,这个元素需要加入到排序的区间
                // 比如  10 9 7
                // 最小值是 10 ,而 7 小于 10,所以 7 需要加入到排序的区间
                // 因此更新 n 的值为 i,说明此时遍历的那些元素中 i 是最靠右的那个数
                n = i;
            }
        }


        // m 和 n 这两个数之间就是要排序的区间,返回即可
        return new int[]{m,n};

    }
}

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-05-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 五分钟学算法 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、题目描述
  • 二、题目解析
  • 三、参考代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档