热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Facebook面试题:和大于S的最小子数组

Tips:FB爱考原题,但是基本需要给到最优解,如果先给出一般解法再给出优化思路,时间往往来不及。分享面试遇到的题。给定一个由n个正整数组成的数组和一个正整数

Tips:FB 爱考原题,但是基本需要给到最优解,如果先给出一般解法再给出优化思路,时间往往来不及。

分享面试遇到的题。

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

做题地址

样例 1:

1
2
3
输入: [2,3,1,2,4,3], s = 7

输出: 2

解释: 子数组 [4,3] 是该条件下的最小长度子数组。


样例 2:

1
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)。变量只需要常数空间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
            // 滑窗右边界扩张

            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;

    }

}

厉害!大佬是在面试当场想出 O(n)时间的解法的?

LeetCode

209. Minimum Size Subarray Sum


推荐阅读
  • POJ 2482 星空中的星星:利用线段树与扫描线算法解决
    在《POJ 2482 星空中的星星》问题中,通过运用线段树和扫描线算法,可以高效地解决星星在窗口内的计数问题。该方法不仅能够快速处理大规模数据,还能确保时间复杂度的最优性,适用于各种复杂的星空模拟场景。 ... [详细]
  • 在《Linux高性能服务器编程》一书中,第3.2节深入探讨了TCP报头的结构与功能。TCP报头是每个TCP数据段中不可或缺的部分,它不仅包含了源端口和目的端口的信息,还负责管理TCP连接的状态和控制。本节内容详尽地解析了TCP报头的各项字段及其作用,为读者提供了深入理解TCP协议的基础。 ... [详细]
  • 本文将继续探讨 JavaScript 函数式编程的高级技巧及其实际应用。通过一个具体的寻路算法示例,我们将深入分析如何利用函数式编程的思想解决复杂问题。示例中,节点之间的连线代表路径,连线上的数字表示两点间的距离。我们将详细讲解如何通过递归和高阶函数等技术实现高效的寻路算法。 ... [详细]
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
  • Python进阶笔记:深入理解装饰器、生成器与迭代器的应用
    本文深入探讨了Python中的装饰器、生成器和迭代器的应用。装饰器本质上是一个函数,用于在不修改原函数代码和调用方式的前提下为其添加额外功能。实现装饰器需要掌握闭包、高阶函数等基础知识。生成器通过 `yield` 语句提供了一种高效生成和处理大量数据的方法,而迭代器则是一种可以逐个访问集合中元素的对象。文章详细解析了这些概念的原理和实际应用案例,帮助读者更好地理解和使用这些高级特性。 ... [详细]
  • 泰波那契数列与斐波那契数列类似,但其计算方法有所不同。本文详细解析了如何高效计算第 N 个泰波那契数,并提供了一种基于动态规划的优化算法。通过使用数组记录中间结果,避免了重复计算,显著提高了算法的执行效率。代码示例展示了具体的实现方法,帮助读者更好地理解和应用这一算法。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • 在C语言中,指针的高级应用及其实例分析具有重要意义。通过使用 `&` 符号可以获取变量的内存地址,而 `*` 符号则用于定义指针变量。例如,`int *p;` 定义了一个指向整型的指针变量 `p`。其中,`p` 代表指针变量本身,而 `*p` 则表示指针所指向的内存地址中的内容。此外,指针在不同函数中可以具有相同的变量名,但其作用域和生命周期会有所不同。指针的灵活运用能够有效提升程序的效率和可维护性。 ... [详细]
  • 在本文中,我们将详细介绍如何构建一个用于自动回复消息的XML类。当微信服务器接收到用户消息时,该类将生成相应的自动回复消息。以下是具体的代码实现:```phpclass We_Xml { // 代码内容}```通过这个类,开发者可以轻松地处理各种消息类型,并实现高效的自动回复功能。我们将深入探讨类的各个方法和属性,帮助读者更好地理解和应用这一技术。 ... [详细]
  • C++ 异步编程中获取线程执行结果的方法与技巧及其在前端开发中的应用探讨
    本文探讨了C++异步编程中获取线程执行结果的方法与技巧,并深入分析了这些技术在前端开发中的应用。通过对比不同的异步编程模型,本文详细介绍了如何高效地处理多线程任务,确保程序的稳定性和性能。同时,文章还结合实际案例,展示了这些方法在前端异步编程中的具体实现和优化策略。 ... [详细]
  • 在多年使用Java 8进行新应用开发和现有应用迁移的过程中,我总结了一些非常实用的技术技巧。虽然我不赞同“最佳实践”这一术语,因为它可能暗示了通用的解决方案,但这些技巧在实际项目中确实能够显著提升开发效率和代码质量。本文将深入解析并探讨这四大高级技巧的具体应用,帮助开发者更好地利用Java 8的强大功能。 ... [详细]
  • 本文介绍了如何利用ObjectMapper实现JSON与JavaBean之间的高效转换。ObjectMapper是Jackson库的核心组件,能够便捷地将Java对象序列化为JSON格式,并支持从JSON、XML以及文件等多种数据源反序列化为Java对象。此外,还探讨了在实际应用中如何优化转换性能,以提升系统整体效率。 ... [详细]
  • 本文探讨了一种高效的算法,用于生成所有数字(0-9)的六位组合,允许重复使用数字,并确保这些组合的和等于给定的整数N。该算法通过优化搜索策略,显著提高了计算效率,适用于大规模数据处理和组合优化问题。 ... [详细]
  • 枚举类中enum关键字的常见应用与实践
    在枚举类中,`enum`关键字具有重要的作用,本文探讨了其常见的应用场景与实践。特别指出,枚举对象必须置于枚举类的首行,否则将导致编译错误。通过具体的代码示例,详细解析了这一规则及其背后的原理,帮助开发者更好地理解和使用枚举类。 ... [详细]
  • 在洛谷 P1344 的坏牛奶追踪问题中,第一问要求计算最小割,而第二问则需要找到割边数量最少的最小割。通过为每条边附加一个单位权值,可以在求解最小割时优先选择边数较少的方案,从而同时解决两个问题。这种策略不仅简化了问题的求解过程,还确保了结果的最优性。 ... [详细]
author-avatar
蘚小凤_950
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有