IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> LeetCode题目209 长度最小的子数组 -> 正文阅读

[数据结构与算法]LeetCode题目209 长度最小的子数组

题目分析

在这里插入图片描述


题目分析

针对一个数组求符合长度长度最小的连续子数组。在数组或者字符串中根据约束条件求满足条件的连续数组,很明显可以通过滑动窗口的方法来解决。


解法一:滑动窗口

滑动窗口的代码如下,基本的滑动窗口套路

public int minSubArrayLen(int target, int[] nums) {
        //窗口左边界
        int left = 0;
        //窗口右边界
        int right = 0;
        //窗口中当前和
        int curSum = 0;
        //最小长度值
        int minLen = Integer.MAX_VALUE;
        while(right < nums.length){
            //累加
            curSum += nums[right];
            //当满足题目中的约束条件时 缩小窗口 即增加左边界的值
            while (curSum >= target){
                minLen = Math.min(minLen, right - left + 1);
                curSum -= nums[left];
                left++;
            }
            right++;
        }
        //判断是否有符合条件的值 存在则返回 不存在返回0
        return minLen == Integer.MAX_VALUE ? 0 : minLen;
    }

时间复杂度:O(n),其中n是数组的长度,right和left最多移动n次。
空间复杂度:O(1)

解法二:前缀和 + 滑动窗口

题目还有个进阶,即是否可以尝试在时间复杂度O(nlog(n))解决,看到时间复杂度设计到log(n),题目又涉及到数组,那么肯定是用二分查找,但是二分查找的数组必须有序,原来的数组无序,怎么用二分查找呢?分析题目,发现题目是求和,那能不能用前缀和呢?题目的约束条件是数组中的每个数字都是正数,因此,数组的前缀和数组一定是有序的。因此可以利用前缀和+二分查找来求解。参考leetcode官方题解代码,代码示例如下:

public int minSubArrayLen(int target, int[] nums) {
      //前缀和数组
        int length = nums.length;
        int[] sum = new int[length + 1];
        int ans = Integer.MAX_VALUE;
        //前缀和数组求解
        for(int i = 1; i <= length; ++i){
            sum[i] = sum[i - 1] + nums[i - 1];
        }
        for(int i = 1; i <= length; ++i){
            int sumValue = target + sum[i-1];
            //找到前缀和数组中等于或者比sumValue大的第一个元素
            int bound = Arrays.binarySearch(sum, sumValue);
            if(bound < 0){
                bound = -bound - 1;
            }
            //sum的长度是length+1 当找不到的时候返回的是length+2
            //处理后等于length+1  因此这个位置一定返回的是false
            if(bound <= length){
                ans = Math.min(ans, bound - (i - 1));
            }
        }
        return ans == Integer.MAX_VALUE ? 0 : ans;
    }

虽然这种解法相比滑动窗口的解法复杂度增加了,但是为我们提供了一种新的思路,即看到log(n),联想到二分,联想到有序,进而联想到前缀和,最终可以写出上述解法。


Java中Arrays.binarySearch()用法

上面解法二用到了Arrays.binarySearch()这个api,之前只知道是在数组中对于目标数字进行二分查找,并且只在目标值存在的情况下使用,今天在理解解法二的时候,发现在目标值不存在的时候,返回值很有趣,之前没有记录过,特意记录下:

  • 如果该值存在 则直接返回下标索引
  • 如果该值不存在,返回第一个比目标值大的位置的索引值(但是此时,索引值的计算从0开始)的相反数

简单代码测试如下:

int[] info = {1,2,3,4,5,8,9};
        //存在 则返回目标值的索引值 2
        System.out.println(Arrays.binarySearch(info, 3));
        //不存在 返回第一个必它大的值的索引
        // 此时是8,但是索引从1开始计算,则索引是5+1=6
        //返回相反数 所以输出-6
        System.out.println(Arrays.binarySearch(info, 7));
        //不存在 返回第一个必它大的值的索引
        // 数组中不存在任何比它还大的值 则直接返回数组的长度 + 1 = 7 + 1 = 8
        //返回相反数 所以输出-8
        System.out.println(Arrays.binarySearch(info, 10));

总结

如有错误,恳请大家批评指正,日拱一卒,功不唐捐。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-01 17:57:48  更:2021-12-01 18:00:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 14:49:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码