LeetCode刷题——最短无序连续子数组#581#Medium

最短无序连续子数组的思路探讨与源码
     最短无序连续子数组的题目如下图,该题属于数组和排序类型的题目,主要考察对于数组本身和排序方法的使用和理解。本文的题目作者想到2种方法,分别是排序方法和区间单遍历方法,其中排序方法使用java进行编写,而区间单遍历方法使用Python进行编写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
在这里插入图片描述
    本人认为该题目可以使用排序的方法,首先获取数组的长度进行判断,如果是小于2的数组则直接返回0的结果即可,然后使用遍历先对数组进行一次遍历判断,如果数组本身就是有顺序的,那就直接返回0的结果就行了。然后开始将原来的数组赋值拷贝为另一个数组,把拷贝以后的数组进行排序,然后从数组的两端开始与排序后的数组进行元素值的比较,找到数组的两边的第一个不相同的数字,然后计算下标之间的差值并加1以后,就是最短的子数组的长度。那么按照这个思路我们的Java代码如下:

#喷火龙与水箭龟
class Solution {
    public int findUnsortedSubarray(int[] nums) {
        int numLen = nums.length;
		if (numLen == 0 || numLen == 1){
			return 0;
		}
		if (sortFun(nums)) {
            return 0;
        }
        int[] arrSort = new int[numLen];
        System.arraycopy(nums,0,arrSort,0,numLen);
        Arrays.sort(arrSort);
        int begin = 0;
        while (arrSort[begin] == nums[begin]) {
            begin=begin+1;
        }
        int end = numLen - 1;
        while (arrSort[end] == nums[end]) {
            end=end-1;
        }
		int count = end - begin + 1;
        return count;
    }
    public boolean sortFun(int[] arr) {
        for (int ir = 1; ir < arr.length; ir++) {
            if (arr[ir] < arr[ir - 1]) {
                return false;
            }
        }
        return true;
    }
}

在这里插入图片描述
    显然,我们看到排序方法的效率比较一般,所以还可以使用单次遍历的方法进行处理,这种方法其实是利用了有序数组内部的元素单调性的特性。首先对数组的长度进行判断,如果小于2则直接返回0的结果。然后将各个参数进行初始化,开始遍历数组,如果元素比最大值要小则将元素的下标赋值给右边的区间下标,反之则将元素的值赋值给最大值;如果当前区间的右下标,也就是根据数组长度减去当前下标后再减1的下标,它的值如果比最小值要大的话,那么就将右边的下标赋值给区间的左下标,反之则将右边下标对应的元素赋值给最小值。如果最终右下标是初始值那么就返回0,反之则返回区间左右下标的差值再加1的结果,也就是区间长度。所以按照这个思路就可以解决,下面是Python代码部分:

#喷火龙与水箭龟
class Solution:
    def findUnsortedSubarray(self, nums: List[int]) -> int:
        numLen = len(nums)
        if(numLen==0 or numLen==1):
            return 0
        maxNum = float("-inf")
        minNum = float("inf")
        begin = -1
        end = -1
        for jr in range(numLen):
            if(maxNum > nums[jr]):
                end = jr
            else:
                maxNum = nums[jr]
            if(minNum < nums[numLen - jr - 1]):
                begin = numLen - jr - 1
            else:
                minNum = nums[numLen - jr - 1]
        if(end == -1):
            return 0
        else:
            count = end - begin + 1
            return count

在这里插入图片描述
    从结果来说java版本的排序方法的效率比较一般,而python版本的单次遍历方法的速度也不是特别快,但应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。

猜你喜欢

转载自blog.csdn.net/qq_26727101/article/details/120468049