LeetCode算法题-Shortest Unsorted Continuous Subarray(Java实现)

这是悦乐书的第267次更新,第281篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第134题(顺位题号是581)。给定一个整数数组,找到一个连续的子数组,按升序对该子数组进行排序,使得整个数组也按升序排序。找到最短的无序连续子数组并输出其长度。例如:

输入:[2,6,4,8,10,9,15]
输出:5
说明:按升序对[6,4,8,10,9]子数组进行排序,以使整个数组按升序排序。

注意:

  • 数组的长度在[1,100]范围内。
  • 数组可能包含重复项,因此这里的升序表示<=。

本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。

02 第一种解法

特殊情况:数组第一个元素大于数组最后一个元素,直接返回整个数组的长度即可。

正常情况:使用两层for循环,外层循环每次获取到一个元素,内层循环就从其后面一位开始,往后比较,如果当前元素比后面的元素大,将其索引记录下来,如果后面遇到了更大的元素,就将索引更新为较大的索引,此索引将作为结束位置索引。

而外层循环用来参与比较的当前元素,在当前元素比后面的元素大时,保留当前元素的索引,如果后面继续出现,就取其中较小的,此索引将作为开始位置索引。最后,如果结束位置的索引值大于开始位置的索引值,就两者相减并加1,反之返回0,表示数组有序。

此解法的时间复杂度是O(n^2),空间复杂度是O(1)。

public int findUnsortedSubarray(int[] nums) {
    if (nums[0] > nums[nums.length-1]) {
        return nums.length;
    }
    int start = 0, end = nums.length;
    for (int i=0; i<nums.length-1; i++) {
        for (int j=i+1; j<nums.length; j++) {
            if (nums[i] > nums[j]) {
                start = Math.max(start, j);
                end = Math.min(end, i);
            }
        }
    }
    return start - end > 0 ? start - end + 1 : 0;
}

03 第二种解法

特殊情况:数组第一个元素大于数组最后一个元素,直接返回整个数组的长度即可。

正常情况:将数组复制一份出来,然后对复制的数组进行排序,再和原数组进行比较,从头和尾分别循环比较,最后找到起始索引,做减法再加1,就是最短无序连续子数组的长度。

此解法的时间复杂度是O(n log(n)),空间复杂度是O(n)。

public int findUnsortedSubarray2(int[] nums) {
    if (nums[0] > nums[nums.length-1]) {
        return nums.length;
    }
    int[] temp = nums.clone();
    Arrays.sort(temp);
    int start = 0, end = nums.length-1;
    while (start < nums.length && nums[start] == temp[start]) {
        start++;
    }
    while (end > start && nums[end] == temp[end]) {
        end--;
    }
    return end - start + 1;
}

04 第三种解法

定义数组的最大值为数组第一个元素,最小值为倒数第一个元素,从数组第二个元素开始,每次拿当前元素与最大值比较,取较大的一个,拿最小值与倒数第二个(从后往前递增)元素比较取较小的一个,如果最大值大于当前元素,就把当前元素的索引赋值给end,如果最小值小于倒数第二个(从后往前递增)元素,就把倒数第二个(从后往前)元素的索引值赋值给start,最后做减法再加1,要是数组是有序的,最后返回的是0,所以end的初始值为-2,start的初始值为-1。

次解法的时间复杂度是O(n),空间复杂度是O(1)。

public int findUnsortedSubarray3(int[] nums) {
    if (nums[0] > nums[nums.length-1]) {
        return nums.length;
    }
    int n = nums.length, start = -1, end = -2;
    int min = nums[n - 1], max = nums[0];
    for (int i = 1; i < n; ++i) {
        max = Math.max(max, nums[i]);
        min = Math.min(min, nums[n - 1 - i]);
        if (max > nums[i]) {
            end = i;
        }
        if (min < nums[n - 1 - i]) {
            start = n - 1 - i;
        }
    }
    return end - start + 1;
}

05 小结

算法专题目前已日更超过四个月,算法题文章134+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

原文地址:https://www.cnblogs.com/xiaochuan94/p/10474527.html

时间: 2024-08-02 03:05:43

LeetCode算法题-Shortest Unsorted Continuous Subarray(Java实现)的相关文章

LeetCode 581. 最短无序连续子数组(Shortest Unsorted Continuous Subarray)

581. 最短无序连续子数组 581. Shortest Unsorted Continuous Subarray 题目描述 给定一个整型数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序. 你找到的子数组应是最短的,请输出它的长度. LeetCode581. Shortest Unsorted Continuous Subarray 示例 1: 输入: [2, 6, 4, 8, 10, 9, 15] 输出: 5 解释: 你只需要对 [6, 4, 8,

LeetCode算法题-Merge Sorted Array(Java实现)

这是悦乐书的第161次更新,第163篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第20题(顺位题号是88).给定两个排序的整数数组nums1和nums2,将nums2中的元素合并到nums1中,并且作为一个排序的数组.在nums1和nums2中初始化的元素个数分别为m和n.假设nums1有足够的空间(大于或等于m + n)来保存nums2中的其他元素.例如: 输入:nums1 = [1,2,3,0,0,0],m = 3,nums2 = [2,5,6],n = 3

LeetCode算法题-Power Of Two(Java实现)

这是悦乐书的第194次更新,第200篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第56题(顺位题号是231).给定一个整数,写一个函数来确定它是否是2的幂.例如: 输入:1 输出:true 说明:2^0 = 1 输入:16 输出:true 说明:2^4 = 16 输入:218 输出:false 本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试. 02 第一种解法 此解法是做乘法,新建一个变量,

LeetCode算法题-First Bad Version(Java实现-三种解法)

这是悦乐书的第200次更新,第210篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第66题(顺位题号是278).您是产品经理,目前领导团队开发新产品.不幸的是,您产品的最新版本未通过质量检查.由于每个版本都是基于以前的版本开发的,因此坏版本之后的所有版本也是坏的. 假设您有n个版本[1,2,...,n]并且您想找出第一个坏的版本,这会导致以下所有版本都不好.您将获得一个API bool isBadVersion(版本),它将返回版本是否错误. 实现一个函数来查找第一

LeetCode算法题-Power of Four(Java实现-六种解法)

这是悦乐书的第205次更新,第216篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第72题(顺位题号是342).给定一个整数(带符号的32位),写一个函数来检查它是否为4的幂.例如: 输入:16 输出:true 输入:5 输出:false 跟进:你可以在没有循环/递归的情况下解决它吗? 本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试. 02 第一种解法 特殊情况:当num小于等于1时,直接返回

LeetCode算法题-Valid Perfect Square(Java实现-四种解法)

这是悦乐书的第209次更新,第221篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第77题(顺位题号是367).给定正整数num,写一个函数,如果num是一个完美的正方形,则返回True,否则返回False.例如: 输入:16 输出:true 输入:14 输出:false 注意:不要使用任何内置库函数,例如sqrt. 本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试. 02 第一种解法 暴力解法

LeetCode算法题-Find the Difference(Java实现-五种解法)

这是悦乐书的第214次更新,第227篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第82题(顺位题号是389).给定两个字符串s和t,它们只包含小写字母.字符串t由随机混洗字符串s生成,然后在随机位置再添加一个字母.找到t中添加的字母.例如: 输入:s ="abcd", t ="abcde" 输出:'e' 说明:'e'是添加的字母. 本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Jav

LeetCode算法题-License Key Formatting(Java实现)

这是悦乐书的第241次更新,第254篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第108题(顺位题号是482).您将获得一个表示为字符串S的许可证密钥,该字符串仅包含字母数字字符和短划线.该字符串被N个破折号分成N + 1个组. 给定数字K,我们希望重新格式化字符串,使得每个组包含正好的K个字符,但第一个组可能比K短,但仍然必须包含至少一个字符.此外,必须在两个组之间插入短划线,并且所有小写字母都应转换为大写.给定非空字符串S和数字K,根据上述规则格式化字符串.例

LeetCode算法题-Construct the Rectangle(Java实现)

这是悦乐书的第243次更新,第256篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第110题(顺位题号是492).对于Web开发人员,了解如何设计网页的大小非常重要.因此,给定一个特定的矩形网页区域,您现在的工作是设计一个矩形网页,其长度L和宽度W满足以下要求: 1.您设计的矩形网页区域必须等于给定的目标区域. 2.宽度W不应大于长度L,这意味着L> = W. 3.长度L和宽度W之间的差异应尽可能小. 您需要按顺序输出您设计的网页的长度L和宽度W. 例: 输入:4