乘积小于K的子数组之滑动窗口

前言

滑动窗口可以解决连续子数组问题,以O(n)的时间复杂度为开销。每个节点最多访问两个,所以要思考O(n2)为什么每个节点要被访问N次?

一、乘积小于K的子数组

在这里插入图片描述

二、题解

滑动窗口,每改变一次窗口大小,记一部分数,如此反复,每次计自己该计的数,不给下一次带来额外麻烦。各司其职,完成大问题的解决。

package com.xhu.offer.offerII;

//乘积小于K的子数组
public class NumSubarrayProductLessThanK {
    //总结:注意审题,都是正整数,这些条件可能是降低时空的因素,甚至可能是解题的关键。
    //总结:代码是给机器看的,是教机器一步一步解决问题的,也就是拆解了问题,不要上来就想if解决所有问题,要拆解成一块一块的循环体。
    //总结:找到规律,即核心迭代块。(所以说循环很关键,循环思维真的很关键。)人要有算法的解决问题,不是暴力解决问题,这样机器才能按照算法走,减少计算量。
    //总结:从小问题到大问题,多个简单问题堆叠成一个复杂问题,复杂性体现在多个简单问题之间碰撞所产生的多现象性。看起来就会很复杂,需挖掘复杂问题中暗含的简单问题。
    //人脑知道该以这样的方式来算,但是没这个时间和超强记忆力,只是借助计算机来算,而思想体现在自己的逻辑,这个逻辑体现在巧妙,而不是时空量去堆积。
    //算法题就是用来训练逻辑的,没有那么多的if,主要是循环的核心体,和相应的数据结构应用。(这是面对算法体的态度和角度去看它,去挖掘,不是无方向无目的的)
    //以整体的方式看数组,比如把数组拆成左中右数组;以局部的方式看内部处理;从局部解决向整体靠近,完成整体的解决。
    //如,当数组只有一个元素时,该怎么解决?有两个时,该怎么解决?有三个时,可不可以利用2+1解决?n个时,是否可以当作(n - 1) + 1解决。不同情况的相同解决点在那里?
    public int numSubarrayProductLessThanK(int[] nums, int k) {
        //滑动窗口,毕竟都是正整数。
        if (k == 0) return 0;

        int count = 0;

        int begin = 0, sum = 1;
        for (int i = 0; i < nums.length; i++) {
            sum *= nums[i];

            if (sum < k) count += i - begin + 1;//关键代码,关键思想体现,只要连续子数组的sum小于k,那么就有subNums.length个积小于K
            if (sum >= k) {
                while (begin <= i) if ((sum /= nums[begin++]) < k) break;

                count += i - begin + 1;
            }
        }
        return count;
    }
}

总结

1)总结:注意审题,都是正整数,这些条件可能是降低时空的因素,甚至可能是解题的关键。
2)总结:代码是给机器看的,是教机器一步一步解决问题的,也就是拆解了问题,不要上来就想if解决所有问题,要拆解成一块一块的循环体。
3)总结:找到规律,即核心迭代块。(所以说循环很关键,循环思维真的很关键。)人要有算法的解决问题,不是暴力解决问题,这样机器才能按照算法走,减少计算量。
4)总结:从小问题到大问题,多个简单问题堆叠成一个复杂问题,复杂性体现在多个简单问题之间碰撞所产生的多现象性。看起来就会很复杂,需挖掘复杂问题中暗含的简单问题。
5)人脑知道该以这样的方式来算,但是没这个时间和超强记忆力,只是借助计算机来算,而思想体现在自己的逻辑,这个逻辑体现在巧妙,而不是时空量去堆积。
6)算法题就是用来训练逻辑的,没有那么多的if,主要是循环的核心体,和相应的数据结构应用。(这是面对算法题的态度和角度去看它,去挖掘,不是无方向无目的的)
7)以整体的方式看数组,比如把数组拆成左中右数组;以局部的方式看内部处理;从局部解决向整体靠近,完成整体的解决。
如,当数组只有一个元素时,该怎么解决?有两个时,该怎么解决?有三个时,可不可以利用2+1解决?n个时,是否可以当作(n - 1) + 1解决。不同情况的相同解决点在那里?

参考文献

[1] LeetCode 原题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值