【算法】数组|长度最小的数组

数组:存放在连续内存空间上的相同类型数据的集合

  • 下标从0开始
  • 内存地址是连续的

一.长度最小的数组

LeetCode题目链接209. 长度最小的子数组

暴力法

  • 思路:采用暴力解法可以直接求得每个满足条件的子数组,并进行比较拿到长度最小的数组,故需要遍历数组的每个元素作为每个子数组的起始元素,然后往后求和直到>=目标值即可停止,因为往后没有必要了我们需要的是长度最短的子数组。另外值得一提都是为了避免不必要的循环,另加了个终止判断:当J走到数组最后一个元素时,也并没有满足子数组之和>=目标值,说明子数组起始元素i已经没有往后移动的必要了,就可以直接返回结果。
  • 代码实现
public static int minSubArrayLen(int target, int[] nums) {
  int min = Integer.MAX_VALUE;
  for (int i = 0; i < nums.length; i++) {
    int j = i;
    int sum = 0;
    while (j < nums.length) {
      sum += nums[j++];
      if (sum >= target) {
        if (min > (j - i)) {
          min = j - i;
        }
        break;
      }
      // 优化:避免不必要的循环,避免超时问题
      if(j == nums.length || min == 1){
        return min == Integer.MAX_VALUE ? 0 : min;
      }
    }
  }
  return min == Integer.MAX_VALUE ? 0 : min;
}
  • 复杂度分析

    时间复杂度:O(n^2)

    空间复杂度:O(1)

滑动窗口(双指针)

  • 思路滑动窗口是一种基于双指针的一种思想,两个指针指向的元素之间形成一个窗口。

    分类:窗口有两类,一种是固定大小类的窗口,一类是大小动态变化的窗口。

    该题则用的是大小动态变化的窗口。可什么要使用该思想呢,还要回到题目上来,暴力破解是遍历元素作为子数组的起始位置,而是否可以遍历元素作为子数组的终止位置呢,循环内已然是求该元素之前子数组的元素之和sum,当sum>=target时,则该元素为终止位置的子数组可满足条件,但是请注意该子数组是最小的数组嘛,就需要将起始位置向前移动来判断是否依然满足条件sum>=target,当不满足时则继续移动终止位置。

  • 代码实现

public static int minSubArrayLen2(int target, int[] nums) {
  int left = 0, right = 0, min = Integer.MAX_VALUE, sum = 0;
  while(right < nums.length){
    sum += nums[right];
    while (sum >= target) {
      min = Math.min(min, right - left + 1);
      sum -= nums[left];
      left++;
    }
    right++;
  }
  return min == Integer.MAX_VALUE ? 0 :min;
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值