day63-day64-day65【代码随想录】二刷哈希表

本文介绍了五道编程题,主要涉及使用前缀和和哈希表的解题策略。题目包括得到K个黑块的最少涂色次数、使数组和能被P整除、和可被K整除的子数组、字母与数字以及寻找最长连续数组。每道题都提供了相应的Java代码实现,展示了如何运用这些算法技巧解决问题。
摘要由CSDN通过智能技术生成


前言

1、得到 K 个黑块的最少涂色次数
2、使数组和能被 P 整除
3、和可被 K 整除的子数组
4、字母与数字
5、连续数组


一、每日一题63:得到 K 个黑块的最少涂色次数(力扣2379)

在这里插入图片描述
较为简单的滑动窗口问题,直接AC

class Solution {
    public int minimumRecolors(String blocks, int k) {
        int left = 0;
        int right = k-1;
        int length = blocks.length();
        int reFlash=Integer.MAX_VALUE;
        int count = 0;
        while(right<=length-1){ //最小滑动窗口 找到满足条件的窗口 然后压缩左边界
            //更新操作数
            for(int i = left;i<=right;i++){
                if(blocks.charAt(i)=='W'){
                    count++;
                }
            }
            reFlash = Math.min(reFlash,count);//更新值

            right++;
            left++;
            count=0;
        }
        return reFlash;
    }
}

二、每日一题64:使数组和能被 P 整除(力扣1590)【前缀和+哈希表】

在这里插入图片描述
前缀和+哈希表
类似于之前的 力扣560 和为 K 的子数组
加了一些同余知识
在这里插入图片描述
大佬题解

class Solution {
    public int minSubarray(int[] nums, int p) {
        int sum = 0;
        for(int num:nums){
            sum= (sum+num)%p;
        }
        int res = nums.length;
        if(sum==0) return 0;
        HashMap<Integer,Integer> map = new HashMap<>();
        map.put(0,-1);
        int pre = 0;
        for(int i=0;i<nums.length;i++){
            pre = (pre+nums[i])%p;
            map.put(pre,i);
            int compare = (pre-sum+p)%p;
            if(map.containsKey(compare)){
                int j = map.get(compare);
                res = Math.min(res,i-j);
            }    
        }
        return res==nums.length? -1:res;
    }
}

三、和可被 K 整除的子数组(力扣974)【前缀和+哈希表】

在这里插入图片描述
分析:
在做完每日一题 1590 后,这道题直接可以AC

class Solution {
    public int subarraysDivByK(int[] nums, int k) {
        HashMap<Integer,Integer> map = new HashMap<>();
        int pre =0;
        map.put(0,1);
        int res = 0;
        for(int i=0;i<nums.length;i++){
            pre =( (pre+nums[i])%k+k)%k;

            if(map.containsKey(pre)){
                res += map.get(pre);
            }
            map.put(pre,map.getOrDefault(pre,0)+1);
        }
        return res;
        
    }
}

四、每日一题65:字母与数字(面试题 17.05)【前缀和+哈希表】

在这里插入图片描述
分析:
连续---->前缀和+哈希表
怎么去联系到一起?
在这里插入图片描述
map.putIfAbsent(pre,i); 这个函数非常好用!!!!

class Solution {
    public String[] findLongestSubarray(String[] array) {
    
        HashMap<Integer,Integer>map = new HashMap<>();
        int pre = 0;
        int len=0;
        int max = 0;
        int end = 0;
        map.put(0,-1);
        for(int i =0;i<array.length;i++){
            pre += Character.isLetter(array[i].charAt(0))?1:-1;// 字母1 数字-1
            len = i - map.getOrDefault(pre,i);
            if(len>max){
                max = len;
                end = i;
            }
            map.putIfAbsent(pre,i);
        }
        return Arrays.copyOfRange(array, end-max+1, end+1);
    }
}

五、连续数组(力扣525)【前缀和+哈希表】

在这里插入图片描述

分析:
跟上一题几乎一模一样的套路
0记为-1,1几位1;

class Solution {
    public int findMaxLength(int[] nums) {
        HashMap<Integer,Integer> map = new HashMap<>();
        map.put(0,-1);
        int max =0;
        int pre = 0;
        for(int i=0;i<nums.length;i++){
            pre += nums[i]==0?-1:1;//0表示-1  1表示1
            int len = i-map.getOrDefault(pre,i);
            if(len>max){
                max = len;
            }
            map.putIfAbsent(pre,i);
        }
        return max;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值