每日一题 -- leetCode209

115 阅读3分钟

image.png 「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战

前言

每日一题,轻松解题

每日一题为刷题系列 每日刷一题LeetCode题,并且对题目进行分析,分享思路。

正文

:长度最小的子数组

难度:中等

题目要求:

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

交替字符串 是指:相邻字符之间不存在相等情况的字符串。例如,字符串 "010" 和 "1010" 属于交替字符串,但 "0100" 不是。

任意两个字符都可以进行交换,不必相邻 。

分析题目:

在一个数组中,找到他的一个子数组,子数组元素和等于给定的一个整数,如果存在这样的子数组,返回子数组最小的长度,如果不存在,返回0

举个例子

输入: target = 6, nums = [2,3,3,2,4,3]
输出: 2
解释: 子数组 [3,3][2,4] 是该条件下的长度最小的子数组。

:解题

方法一 : 暴力解法

理清思路:

暴力法是最直观的方法。初始化子数组的最小长度为无穷大,枚举数组 \text{nums}nums 中的每个下标作为子数组的开始下标,对于每个开始下标 ii,需要找到大于或等于 ii 的最小下标 jj,使得从 \text{nums}[i]nums[i] 到 \text{nums}[j]nums[j] 的元素和大于或等于 ss,并更新子数组的最小长度(此时子数组的长度是 j-i+1j−i+1)。

编辑代码:

var minSubArrayLen = function(target, nums) {
    var newA = []
    var sum = 0
    var oA = []
     for(var i = 0 ; i<nums.length ; i++){
            sum += nums[i]
     }
     if(sum<target){
         return 0
     }else if(sum>target){
        sum = 0       
        for(var i = 0 ; i<nums.length ; i++){
            sum += nums[i]
            if(sum >= target){
                return 1
            }
            for(var j = i+1 ; j<nums.length ; j++){
                sum += nums[j]
                if(sum>= target){
                    newA = nums.slice(i,j+1)
                    oA.push(newA.length)
                    sum = 0
                    break
                }
            }
            sum = 0
        }
         
     }else{
          return nums.length
     }
       
    var min = Math.min.apply(Math,oA)
    return min
};

方法二 : 移动窗口

理清思路:

一 :使用left,right代表窗口左右边界;sum为窗口里的数字和;min为满足条件时的窗口长度;
二 :循环,在右边界内执行:
1.如果sum大于等于target;更新min,
特殊 : 如果min等于1 直接返回,不会有比1更小子数组了;sum减去左边界的值 left++;
2.否则right++;sum加上右边界的值
最后: 看min是否还是最大值 是的话代表没有找到 返回0 否则返回min

编辑代码:

var minSubArrayLen = function(target, nums) {
    const length = nums.length;
    //使用left,right代表窗口左右边界;sum为窗口里的数字和;min为满足条件时的窗口长度;
    let left = 0;
    let right = 0;
    let sum = nums[0];
    let min = Number.MAX_SAFE_INTEGER;
    while(right < length) {
        //1.如果sum大于等于target;更新min, 如果min等于1 直接返回,sum减去左边界的值 left++;
        if(sum >= target) {
            min = Math.min(min,right-left+1)
            if(min === 1) return min;
            sum -= nums[left];
            left++;
        //2.否则right++;sum加上右边界的值 
        }else{
            right++;
            sum += nums[right];
        }
    }
    //看min是否还是最大值 是的话代表没有找到 返回0  否则返回min
    return min===Number.MAX_SAFE_INTEGER? 0 : min;
};

总结

无论做什么分析最重要,其中我们分析了题目,分析了解题思路,其实在分析完解题思路后,代码其实就是很简单的事情了,养成习惯,无论做什么之前,都要进行分析,这样有助于你更快更好的完成这件事。