滑动窗口系列(定长滑动窗口长度) 8/30

1.所有数对中 数位差之和()

题意:

给定一个nums数组,计算中所有整数数对中 数位差的个数之和;

数位差:某一位上的数字不一样就记作数位差。

eg:12 22; 十位上不一样,数位差为1

思路:

首先计算出一个数字有多少位(题目中给出所有数字的位数都相同这个条件)

然后统计每一位上0-9的个数

最后就可以计算出数位差的个数。

比如说:个位等于0有x个,那么不等于0就有nums.size - x 个,那么数位差就有x*(nums.size-x)/2个

以此类推先计算个位上的。然后计算十位上的...

代码:
class Solution {
    public long sumDigitDifferences(int[] nums) {
        //nums中整数都有相同的长度
        long res=0;
        int size=nums.length;
        int[][] cnt=new int[Integer.toString(nums[0]).length()][10];
        for(int num:nums){
            int index=0;
            while(num>0){
                cnt[index++][num%10]++;
                num/=10;
            }
        }
        for(int i=0;i<cnt.length;i++){
            for(int j=0;j<10;j++){
                res+=(long)cnt[i][j]*(size-cnt[i][j]);
            }
        }
        return res>>1;
    }
}

2.定长子串中原因的最大数目

给你字符串 s 和整数 k 。

请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。

英文中的 元音字母 为(aeiou)。

思路:

1.对字符串中的字符循环,判断是不是元音字母;如果是的话,元音字母数量+1;

2.此时判断滑动窗口的长度是否等于k

   2.1 如果等于 就要判断s.charAt(left)是否是元音字母 如果是的话 数量-1;

   2.2  如果小于 继续循环

3.right++,窗口继续往右扩展

代码:
class Solution {
    public int maxVowels(String s, int k) {
        int left = 0;
        int right = 0;
        int res = 0;
        int amount = 0;
        while (right < s.length()) {
            char ch = s.charAt(right);
            if (isYy(ch)) amount++;
            if (right - left + 1 == k) {
                res = Math.max(res, amount);
                if (isYy(s.charAt(left)))
                    amount -= 1;
                left++;
            }
            right++;
        }
        return res;
    }

    public boolean isYy(char ch) {
        if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u')
            return true;
        return false;
    }
}

3.大小为K且平均值大于等于阈值的子数组数目

给你一个整数数组 arr 和两个整数 k 和 threshold 。

请你返回长度为 k 且平均值大于等于 threshold 的子数组数目。

思路:

对数组遍历循环,当窗口的长度==k的时候,判断平均值是否大于等于阈值,如果大于等于res++;然后left++,num-=nums[left]

代码:
class Solution {
    public int numOfSubarrays(int[] arr, int k, int threshold) {
        int res = 0;
        int left = 0;
        int right = 0;
        int sum = 0;
        while (right < arr.length) {
            sum += arr[right];
            if (right - left + 1 == k) {
                if (sum >= threshold * k) {
                    res++;
                }
                sum -= arr[left];
                left++;
            }
            right++;
        }
        return res;
    }
}

4.拆炸弹

题意:

你有一个炸弹需要拆除,时间紧迫!你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k 。

如果k>0,数组中下标为index的值为后k位数字(>nums.length-1就返前来)的和;

如果k=0,数组中的值都为0;

如果k<0,数组中下标为index的值为前k位数字(<0折后去)的和

思路:

仍然使用固定长度的滑动窗口的思路;

首先对K进行判断,有三种情况;

k>0,开始进行循环遍历数组中的每一个数字,当right-left+1==k或者right+len-left+1==k的时候,res[(left-1)%k]==sum,循环的条件为index<nums.length+k-1(要使数组上每一个位置都有新的和)

k<0,同理

代码:
class Solution {
    public int[] decrypt(int[] code, int k) {
        int[] res=new int[code.length];
        int len=code.length;
        int left=0;
        int right=0;
        int sum=0;
        int index=0;
        if(k==0)return res;
        else if(k>0){
            while(index<code.length+k-1){
                sum+=code[right];
                System.out.println(sum);
                if(right-left+1==k||right+len-left+1==k){
                    res[(left-1+len)%len]=sum;
                    sum-=code[left%len];
                    left=(left+1)%len;
                }
                right=(right+1)%len;
                index++;
            }
        }else{
            k=-k;
            while(index<code.length+k-1){
                sum+=code[right];
                System.out.println(sum);
                if(right-left+1==k||right+len-left+1==k){
                    res[(right+1)%len]=sum;
                    sum-=code[left];
                    left=(left+1)%len;
                }
                right=(right+1)%len;
                index++;
            }
        }
        return res;
    }
}

模版:

class Solution {
    public int numOfSubarrays(int[] arr, int k, int threshold) {
        int res = 0;
        int left = 0;
        int right = 0;
        int sum = 0;
        while (right < arr.length) {
            //1. 根据题目中的要求来计算
            xxxxxxxx
            //2. 此时判断窗口的大小是否等于题目中要求的
            if (right - left + 1 == 窗口长度大小) {
                if (条件) {
                    res++;
                }
            //3.窗口左边的边界移动
                sum -= arr[left];
                left++;
            }
            //4. 窗口右边的边界移动
            right++;
        }
        return res;
    }
}

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值