面试题 16.16. 部分排序
原始题目链接:https://leetcode-cn.com/problems/sub-sort-lcci/
给定一个整数数组,编写一个函数,找出索引m和n,只要将索引区间[m,n]的元素排好序,整个数组就是有序的。注意:n-m尽量最小,也就是说,找出符合条件的最短序列。函数返回值为[m,n],若不存在这样的m和n(例如整个数组是有序的),请返回[-1,-1]。
示例:
输入: [1,2,4,7,10,11,7,12,6,7,16,18,19]
输出: [3,9]
提示:
0 <= len(array) <= 1000000
解题思路:
贪心思想,寻找最右边和最左边的两个满足题目条件的索引,要知道,当前的元素是否需要排序,是因为在它的两边有比它大或小的值存在,所以当前元素需要重新排序才能保持整个数组有序。所以当前值如果它的左边有比它大的值,那么这个当前值的索引为最右边索引的一个待选,正向遍历整个数组,找到这种条件的最右边的索引即可,同理,当前值如果它的右边存在有比它小的值,那么找到这种条件的最左边的索引即可。具体实现看代码。
代码实现:
class Solution:
def subSort(self, array: List[int]) -> List[int]:
n = len(array)
# 记录两个值
# 保存正向遍历数组的时候当前遇到的最大值
maxIndex = float(-inf)
# 保存逆序遍历数组的时候当前遇到的最小值
minIndex = float(inf)
r, l = -1, -1
# 正向遍历:贪心思想,如果当前值array[i]的左边有比它大的值,则array[i]需要重新排序
# 得到最右边满足此条件的索引
for i in range(n):
# 如果当前值的左边最大值比当前值大,则符合索引条件,更新索引
if array[i] < maxIndex:
r = i
# 否则更新当前的最大值
else:
maxIndex = array[i]
# 逆序遍历:贪心思想,如果当前值array[i]的右边有比它小的值,则array[i]需要重新排序
# 得到最左比满足此条件的索引
for i in range(n - 1, -1, -1):
# 如果当前值的右边的最小值比当前值小,则符合索引条件,更新索引
if array[i] > minIndex:
l = i
# 否则更新最小值
else:
minIndex = array[i]
return [l, r]
参考文献:
https://leetcode-cn.com/problems/sub-sort-lcci/solution/mei-ri-suan-fa-day-88-chao-yue-mei-mei-jiao-ni-zen/