我是靠谱客的博主 感动日记本,最近开发中收集的这篇文章主要介绍【算法】剑指 Offer 专项突击版 Day3数组部分【算法】剑指 Offer 专项突击版 Day3数组部分I 【中等】007. 数组中和为 0 的三个数II 【中等】 008. 和大于等于 target 的最短子数组III 【中等】009. 乘积小于 K 的子数组,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

【算法】剑指 Offer 专项突击版 Day3数组部分

题目地址:https://leetcode-cn.com/study-plan/lcof/?progress=wgzvtig

目标:要点总结,分享思路
通俗代码,满足要求快速实现

文章目录

  • 【算法】剑指 Offer 专项突击版 Day3数组部分
  • I 【中等】007. 数组中和为 0 的三个数
  • II 【中等】 008. 和大于等于 target 的最短子数组
  • III 【中等】009. 乘积小于 K 的子数组


I 【中等】007. 数组中和为 0 的三个数

在这里插入图片描述
难度:普通,双指针题

要点

  • 思路:数组排序后,在不重复要求下,设置起始第一个数base,在剩下数字中通过双指针寻找和为target-base的两个数
  • 重点:为什么一定先对数组排序,因为只有排序后才能使用双指针。且先不排序的话,循环中每次寻找也是要排序的,故排序是必需的。(可以先通过暴力遍历思考理解)
               这道题想到双指针就可以做出来了,但是加入一些剪枝可以大大降低时间复杂度

          剪枝1:如果第一个数字已经成功使用过,就不需要双指针重复找剩下两个数
          剪枝2:在有序数组条件下,如果两数最值都不满足target直接更换base进入下一轮寻找

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        if len(nums)<3:return []
        ans,ans_set,first_num_set = [],set(),set()
        nums.sort()

        for i in range(len(nums)-2):
            base = nums[i] # 第一个数字
            target = 0-base 
            if base not in first_num_set: # 剪枝1
                left,right = i+1,len(nums)-1
                if nums[left]+nums[left+1]>target or nums[right] + nums[right-1]<target:
                    continue  # 剪枝2
                while left<right:
                    if nums[left]+nums[right] < target:
                        left+=1
                    elif nums[left]+nums[right]>target:
                        right-=1
                    else:
                        if (base,nums[left],nums[right]) not in ans_set:
                            ans.append([base,nums[left],nums[right]])
                            ans_set.add((base,nums[left],nums[right]))
                            first_num_set.add(base)
                        left+=1
                        
        return ans

总结:两数之和、三数之和等问题可以考虑双指针+剪枝解决

II 【中等】 008. 和大于等于 target 的最短子数组

在这里插入图片描述

难度:普通,滑动窗口题

要点:两种方法

  • 思路:(1)设置双指针,右指针不断向右移,当窗口和>目标值时记录窗口长度并不断移动左指针,时间复杂度 O ( n ) O(n) O(n)
  •    (2)前缀和+二分查找,因题目中明确数组中均为正数,这样就满足了前缀和递增有序,时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn),题目有这个思考要求,理解就好
  • 小技巧:这种最小值长度问题可以先将结果ans设置成数组长度+1,这样后面判断一下就知道ans是否有改变,因为满足条件的最大值长度就是数组长度

滑动窗口版

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        # 滑动窗口——推荐
        if not nums:return 0
        left,right=0,0
        total = 0
        ans = len(nums)+1 # 设置成最大长度+1
        while right<len(nums):
            total+=nums[right]
            while total>=target:
                ans = min(ans,right-left+1)
                total -= nums[left]
                left  += 1
            right+=1
        return ans if ans!=len(nums)+1 else 0

前缀和+滑动窗口

图例全部详细请见
【花落&月缺】反正我也没弄白前缀和方法哪里比较好……(T_T)(前缀和、滑动窗口)
这里截一张他的图便于理解
在这里插入图片描述

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        # 前缀和 + 二分查找
        sums = [0]
        ans = len(nums)+1
        for i in range(len(nums)):
            sums.append(sums[-1]+nums[i])
        
        for i in range(1,len(sums)):
            find = target+sums[i-1]
            middle = bisect.bisect_left(sums,find)
            if middle!=len(sums):  
                ans = min(middle-i+1,ans)
        return ans if ans!=len(nums)+1 else 0

III 【中等】009. 乘积小于 K 的子数组

在这里插入图片描述
难度:简单的滑动窗口题

要点

  • 思路:双指针解决滑动窗口问题,窗口不断向右移动,即右指针不断增加,当窗口内乘积大于等于目标k时,缩小窗口,即左指针不断减小
class Solution:
    def numSubarrayProductLessThanK(self, nums: List[int], k: int) -> int:
        if k<=1: return 0 
        left,right,ans,multi = 0,0,0,1
        while right<len(nums):
            multi *= nums[right]
            while multi >= k:
                multi /= nums[left]
                left+=1
            ans += right - left+1
            right += 1
        return ans

最后

以上就是感动日记本为你收集整理的【算法】剑指 Offer 专项突击版 Day3数组部分【算法】剑指 Offer 专项突击版 Day3数组部分I 【中等】007. 数组中和为 0 的三个数II 【中等】 008. 和大于等于 target 的最短子数组III 【中等】009. 乘积小于 K 的子数组的全部内容,希望文章能够帮你解决【算法】剑指 Offer 专项突击版 Day3数组部分【算法】剑指 Offer 专项突击版 Day3数组部分I 【中等】007. 数组中和为 0 的三个数II 【中等】 008. 和大于等于 target 的最短子数组III 【中等】009. 乘积小于 K 的子数组所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部