大厂面试真题详解:和大于S的最小子数组

简介: 大厂面试真题详解:和大于S的最小子数组

给定一个由 n 个正整数组成的数组和一个正整数 s ,请找出该数组中满足其和 ≥ s 的最小长度子数组。如果无解,则返回 -1。

在线评测地址:领扣题库官网

样例 1:

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

样例 2:

输入: [1, 2, 3, 4, 5], s = 100
输出: -1

解题思路

  • 如果采用暴力解法,用变量i从左到右遍历数组,变量j从i到数组尾部遍历,将i到j内的元素遍历求和,找到和大于s的最短数组。时间复杂度为O(n^3)。
  • 对暴力法进行优化,使用累加器来进行求和,那么求和这步只需要O(1)。总的时间复杂度为O(n^2)。
  • 使用二分法来继续优化,对于左端点i,我们用二分法来寻找j。首先建立前缀和数组sum,对于每个i,在i到尾部这段区间上二分查找,找到满足sum[j] - sum[i] > S的最小的j。总的时间复杂度为O(nlog(n))。
  • 最优解法是采用滑窗。我们用 2 个指针,一个指向子数组开始的位置,一个指向数子组最后的位置,并维护区间内的和 curr_sum大于等于s 同时数组长度最小,实时更新最短的数组长度res。时间复杂度为O(n)。

算法流程

  • 初始化左指针left和右指针right指向0,子数组和curr_sum为0。
  • 右指针right遍历nums数组,即不断移动滑窗右端

    • 更新子数组的和,curr_sum += nums[right]
    • 当子数组和满足条件,即curr_cum >= s时

      • 更新res = min(res, right - left + 1),其中right - left + 1是当前子数组的长度
      • curr_sum -= nums[left],然后左指针右移,继续判断当前数组和是否满足条件
  • 返回res

复杂度分析

  • 时间复杂度:O(n) 。每个指针移动都需要O(n)的时间。每个元素至多被访问两次,一次被右端点访问,一次被左端点访问。
  • 空间复杂度:O(1)。变量只需要常数空间。
public class Solution {
    /**
     * @param nums: an array of integers
     * @param s: An integer
     * @return: an integer representing the minimum size of subarray
     */
    public int minimumSize(int[] nums, int s) {
        int left = 0, currSum = 0, res = Integer.MAX_VALUE;
        for (int right = 0; right < nums.length; right ++) {
            // 滑窗右边界扩张
            currSum += nums[right];
            // 满足条件
            while (currSum >= s) {
                // 更新res
                res = Math.min(res, right - left + 1);
                // 滑窗左边界收缩
                currSum -= nums[left];
                left ++;
            }
        }
        return res == Integer.MAX_VALUE ? -1: res;
    }
}

更多题解参考:九章官网solution

相关文章
|
6月前
|
算法
【数组相关面试题】LeetCode试题
【数组相关面试题】LeetCode试题
|
6月前
|
存储
力扣面试经典题之数组/字符串
力扣面试经典题之数组/字符串
51 0
|
6月前
|
算法 前端开发
经典面试题:扁平化嵌套数组
经典面试题:扁平化嵌套数组
43 0
|
3月前
|
C语言
【Amazon 面试题1】一个数组,里面得数出现的次数是偶数次,只有一个数出现的次数是奇数次,找出那个出现奇数次的数
本文介绍了解决Amazon面试题的一种方法,即在一个所有数字出现次数都是偶数,除了一个数字出现奇数次的数组中,利用异或运算的性质找出出现奇数次的数字,并提供了C语言实现的代码示例。
65 1
|
3月前
|
Java
Java 基础语法-面试题(54-63道)(数组+类+包)
Java 基础语法-面试题(54-63道)(数组+类+包)
41 16
|
4月前
|
存储 算法
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
|
5月前
|
开发框架 .NET
技术好文共享:面试题:找出数组中只出现一次的2个数(异或的巧妙应用)(出现3次)
技术好文共享:面试题:找出数组中只出现一次的2个数(异或的巧妙应用)(出现3次)
|
5月前
|
数据采集 算法 数据挖掘
LeetCode 题目 80:删除排序数组中的重复项 II【算法面试高频题】
LeetCode 题目 80:删除排序数组中的重复项 II【算法面试高频题】
|
6月前
|
C++
【一刷《剑指Offer》】面试题 14:调整数组顺序使奇数位于偶数前面
【一刷《剑指Offer》】面试题 14:调整数组顺序使奇数位于偶数前面
|
6月前
|
算法 C++
【一刷《剑指Offer》】面试题 8:旋转数组的最小数字
【一刷《剑指Offer》】面试题 8:旋转数组的最小数字