Leetcode刷题 2021.02.02

Leetcode424 替换后的最长重复字符

给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次。在执行上述操作后,找到包含重复字母的最长子串的长度。

注意:字符串长度 和 k 不会超过 10^4。

正常的滑动窗口题,其实对滑动窗口一直掌握的不是很好。经常会出现凭感觉写,然后边界各种调试的情况,要好好整理一下了。

class Solution {
    public int characterReplacement(String s, int k) {
        if (s == null || s.length() == 0) return 0;
        char[] arr = s.toCharArray();
        int i = 0, res = 0, n = arr.length, max = 0;
        //因为都是大写字母,可以用一个长度26的数组保存字符出现的频率
        int[] map = new int[26];
        for(int j = 0; j < n; j++){
        	//先扩大右边窗口
            map[arr[j] - 'A']++;
            max = Math.max(max, map[arr[j] - 'A']);
            //满足特定条件,需要缩小左窗口,这里的条件就是窗口之间的长度要大于k + 窗口之间出现频率最高的字符
            while (j - i + 1 - max > k){
                map[s.charAt(i) - 'A']--;
                i++;
            }
            //更新全局的最大值
            res = Math.max(res, j - i + 1);
        }
        return res;
    }
}

Leetcode1306 跳跃游戏 III

这里有一个非负整数数组 arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i + arr[i] 或者 i - arr[i]。

请你判断自己是否能够跳到对应元素值为 0 的 任一 下标处

注意,不管是什么情况下,你都无法跳到数组之外。

理解了题目意思以后发现就是很基础的搜索提,BFS或者DFS都可以,这里用DFS。

class Solution {
    boolean[] isVisited; 
    public boolean canReach(int[] arr, int start) {
        isVisited = new boolean[arr.length];

        return helper(arr, start);
    }

    private boolean helper(int[] arr, int index){
        if (index < 0 || index >= arr.length || isVisited[index]) return false;
        if (arr[index] == 0) return true;
        isVisited[index] = true;
        //有一个找到了就返回true
        if (helper(arr, index + arr[index])) return true;
        if (helper(arr, index - arr[index])) return true;

        return false;
    }
}

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

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

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

一开始以为是要前缀和来做,后来发现数组的大小是固定的,那就基本没有难度了,就是遍历就行了。话说今天的中等题都出奇的简单。(lll¬ω¬)

class Solution {
    public int numOfSubarrays(int[] arr, int k, int threshold) {
        int n = arr.length;
        if (n < k) return 0;
        int sum = 0;
        //先算一下前k - 1个值的和
        for(int i = 0; i < k - 1; i++){
            sum += arr[i];
        }
        int res = 0, i = 0;
        for(int j = k - 1; j < n; j++){
            sum += arr[j];
            //然后遍历看看平均值受否大于阈值就行了,这里也可以不用除法,用乘法,算是一个小优化吧。
            if ((double)(sum) / k >= threshold){
                res++;
            }
            sum -= arr[i];
            i++;
        }

        return res;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值