LeetCode——713.乘积小于K的子数组

通过万岁!!!

  • 题目:要求在一个数组中,找到所有连续子数组,然后要求子数组的乘积不能超过k,然后问满足条件的子数组的个数。
  • 基础思路:双指针,l在左边,每次让乘积*右指针,然后判断是不是满足条件,如果满足,则ans++,如果不满足,则做指针需要右移一位,这时候让右指针回到做指针的位置即可。但是这样的时间复杂度很高。不过也是一种方法。消耗时间为多少千毫秒。
  • 莫名其妙的进阶思路:我是想通过每个位置上的最长子数组长度进行求解。这样我们在l位置的长度如果是a,那么r=l+a,则i+1位置只需要从l+a的下一个开始找就行了。但是最后发现,这些长度求和就是最终结果,咱也不知道为啥。我还是说一下我进阶的思路,就是我们知道每个位置的最长子数组之后,从这个位置开始,其实我们能拿到的数组个数是1+…+a,也就是(a+1)*a/2,然后下一个位置如果小于a,则表示我们已经计算过了,然后如果等于a,则个数+=2即可,如果大于a,则减去中间重合的部分,也就是减去。但是这个思路我还没有验证对不对,模模糊糊的写的。
  • 技巧:

java代码——基础思路

class Solution {
    public int numSubarrayProductLessThanK(int[] nums, int k) {
        // 滑动窗口,快慢指针
        int n = nums.length;
        int l = 0, r = 0;
        int product = nums[0];// 当前成绩
        int ans = 0;
        while (l <= r && r < n) {// 判断product是不是可以
            if (product < k) {
                if (r < n - 1) {
                    product *= nums[++r];
                } else {// 右指针到头
                    if (l < n - 1) {// 左指针没有到头
                        product = nums[++l];
                        r = l;// r需要回来
                    } else {// 做指针也到头了
                        l++;
                    }
                }
                ans++;
            } else {
                if (l < n - 1) {
                    product = nums[++l];
                    r = l;// r需要回来
                } else {
                    l++;
                }
            }
        }
        return ans;
    }
}

java——莫名其妙的进阶思路

class Solution {
    public int numSubarrayProductLessThanK(int[] nums, int k) {
        // 滑动窗口,快慢指针
        if (k == 0) {
            return 0;
        }
        int n = nums.length;
        int ans = 0, l = 0, r = 0, product = 1;
        int res = 0;
        while (l <= r && r < n) {
            product *= nums[r];
            if (product >= k) {
                res += ans;
                product /= nums[l++];
                if (l - 1 != r)
                    product /= nums[r];// 取消掉本次的乘,因为下面l++,以后还是需要判断这个r是不是可以
                if (l > r) r = l;
                if (ans > 0)
                    ans--;
            } else {
                r++;
                ans++;
            }
        }
        for (int i = n - 1; i >= l; i--) {
            res += (n - i);
        }
        return res;
    }
}
  • 总结:题目还是比较有意思的,不知道为啥莫名其妙的就对了应该是里面有一些数学推导,我没有进行,时间降到了6ms左右,虽然打败的人数不多,但是比基础思路提升了好多。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值