LeetCode每日一题(17)—— 乘积小于 K 的子数组(双指针)

简介: 乘积小于 K 的子数组1.题目2.示例3.思路4.代码

1.题目


给你一个整数数组 nums 和一个整数 k ,请你返回子数组内所有元素的乘积严格小于 k 的连续子数组的数目。


2.示例


示例 1:


输入:nums = [10,5,2,6], k = 100

输出:8

解释:8 个乘积小于 100的子数组分别为:[10]、[5]、[2]、[6]、[10,5]、[5,2]、[2,6]、[5,2,6]。 需要注意的是 [10,5,2]并不是乘积小于 100 的子数组。


示例 2:


输入:nums = [1,2,3], k = 0

输出:0


提示:


1 <= nums.length <= 3 * 104

1 <= nums[i] <= 1000

0 <= k <= 106


3.思路


开始想的是遍历数组,以数组的每一个数开头向后遍历。计算乘积,当乘积不小于k了,再从下一个数字开始向后开始新一轮的遍历。这样可以得到所有的子数组,写完发现题目只要子数组的数量,然后这个方法不出意外的超时了。

官方的代码看不太明白,就用双指针的思路写了第二个方法,只需要理解:右指针每位移到一个新位置,应该加上 right - left + 1 种数组组合就好了。


4.代码


暴力


func numSubarrayProductLessThanK(nums []int, k int) int {
  //暴力
  var ans []int
  var product int
  for i, _ := range nums {
    if nums[i] < k {
      temp := []int{nums[i]}
      ans = append(ans,temp)
      product = nums[i]
      for j := i+1; j < len(nums); j++{
        product = product*nums[j]
        if product < k {
          temp = append(temp, nums[j])
          log.Println(temp,nums[j])
          ans = append(ans, temp)
          log.Println(ans)
        }else {
          break
        }
      }
    }
  }
  return len(ans)
}


双指针


func numSubarrayProductLessThanK(nums []int, k int) int {
  //数组中数的范围是1~1000,所以当k=0时,没有满足要求的数组
  if k == 0 {
    return 0
  }
  //记录区间内的乘积
  product := 1
  var ans,left,right int
  //使右指针移动到右端则结束
  for right < len(nums) {
    //记录乘积
    product *= nums[right]
    //当前区间内的乘积大于等于k,左指针右移并把之前左指针的数除掉
    for product >= k {
      product /= nums[left]
      left++
    }
    //每次右指针位移到一个新位置,应该加上 right - left + 1 种数组组合:
    //  nums[right]
    //  nums[right-1], nums[right]
    //  nums[right-2], nums[right-1], nums[right]
    //  nums[left], ......, nums[right-2], nums[right-1], nums[right]
    //共有 right - left + 1 种
    ans += right - left + 1
    //右指针右移
    right++
  }
  return ans
}
相关文章
|
3天前
|
索引
力扣每日一题 6/17 枚举+双指针
力扣每日一题 6/17 枚举+双指针
6 1
|
3天前
|
算法 测试技术 程序员
力扣经典150题第三十题:长度最小的子数组
力扣经典150题第三十题:长度最小的子数组
6 1
|
21天前
|
存储 算法 数据可视化
【模拟面试问答】深入解析力扣163题:缺失的区间(线性扫描与双指针法详解)
【模拟面试问答】深入解析力扣163题:缺失的区间(线性扫描与双指针法详解)
|
21天前
|
算法 数据挖掘 Java
深入解析力扣167题:两数之和 II(双指针法详解及模拟面试问答)
深入解析力扣167题:两数之和 II(双指针法详解及模拟面试问答)
|
21天前
|
存储 算法 数据挖掘
【模拟面试问答】力扣165题:比较版本号(逐个比较与双指针法详解及模拟面试问答)
【模拟面试问答】力扣165题:比较版本号(逐个比较与双指针法详解及模拟面试问答)
|
21天前
|
存储 算法 数据可视化
深入解析力扣160题:相交链表的解决方法(哈希表法与双指针法详细图解)
深入解析力扣160题:相交链表的解决方法(哈希表法与双指针法详细图解)
技术经验解读:【LeetCode】560.SubarraySumEqualsK子数组和为K
技术经验解读:【LeetCode】560.SubarraySumEqualsK子数组和为K
|
18天前
【LeetCode刷题】前缀和解决问题:742.寻找数组的中心下标、238.除自身以外数组的乘积
【LeetCode刷题】前缀和解决问题:742.寻找数组的中心下标、238.除自身以外数组的乘积
|
18天前
【LeetCode刷题】滑动窗口思想解决问题:长度最小的子数组、无重复字符的最长子串
【LeetCode刷题】滑动窗口思想解决问题:长度最小的子数组、无重复字符的最长子串
|
18天前
|
算法
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表