day55-day56【代码随想录】二刷数组

本文介绍了使用滑动窗口解决字符串排列、字母异位词查找和串联所有单词子串的LeetCode题目,以及每日一题中合并相似物品和寻找矩阵局部最大值的问题。这些例子展示了滑动窗口在处理字符串和数组问题时的有效性。
摘要由CSDN通过智能技术生成


前言

1、字符串的排列
2、找到字符串中所有字母异位词
3、串联所有单词的子串
4、每日一题
5、每日一题


一、字符串的排列(力扣567)【滑动窗口】

给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。

换句话说,s1 的排列之一是 s2 的 子串 。

在这里插入图片描述

class Solution {
    public boolean checkInclusion(String s1, String s2) {
        int left=0;
        int right=0;

        int[] need = new int[128];
        for(int i=0;i<s1.length();i++){
            need[s1.charAt(i)]++;
        }
        int count = s1.length();
        int length = s1.length();

        //滑动窗口
        while(right<s2.length()){
            //判断是否满足条件:
            if(need[s2.charAt(right)]>0){
                count--;
            }
            need[s2.charAt(right)]--;
            if(count==0){
                //缩小窗口左边界
                while(left<right && need[s2.charAt(left)]<0){
                    //说明是可以缩小窗口的
                    need[s2.charAt(left)]++;
                    left++;
                }
                //不能再缩小的时候 判断一下length
                if(right-left+1==length){
                    return true; 
                }
                need[s2.charAt(left)]++;
                left++;
                count++;
            }
            right++;
        }
        return false;
    }
}

二、找到字符串中所有字母异位词(力扣438)【滑动窗口】

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。

在这里插入图片描述

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        int i=0;
        int j=0;
        //用来存放需要的元素
        int[] need = new int[128];
        for(int c=0;c<p.length();c++){
            need[p.charAt(c)]++;
        }
        int count = p.length();
        int length = p.length();

        List<Integer> res = new ArrayList<>();

        while(j<s.length()){
            //判断是否满足条件
            if(need[s.charAt(j)]>0){
                count--;
            }
            need[s.charAt(j)]--; //把右边字符加入窗口
            while(count==0){
                while(i<j && need[s.charAt(i)]<0)//压缩左窗口
                {
                    need[s.charAt(i)]++;
                    i++;
                }
                if(j-i+1==length){
                   //记录结果
                   res.add(i);
                }
                need[s.charAt(i)]++;
                i++;
                count++;
            }
            j++;
        }
        return res;
    }
}

三、串联所有单词的子串(力扣30)【滑动窗口】****【hard】

给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。

s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。

例如,如果 words = [“ab”,“cd”,“ef”], 那么 “abcdef”, “abefcd”,“cdabef”, “cdefab”,“efabcd”, 和 “efcdab” 都是串联子串。 “acdbef” 不是串联子串,因为他不是任何 words 排列的连接。
返回所有串联字串在 s 中的开始索引。你可以以 任意顺序 返回答案。
在这里插入图片描述


class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> res = new ArrayList<>();
        HashMap<String,Integer> need = new HashMap<>();
        //把字典中的单词放到map集合当中
        for(String word : words){
            need.put(word,need.getOrDefault(word,0)+1);
        }
        int n=s.length();
        int sum=words.length;//单词数
        int len=words[0].length();//每个单词的长度
        for(int i=0;i<n-sum*len+1;i++){ //窗口的起始位置
            HashMap<String,Integer> window = new HashMap<>();
            //找出sum个单词
            int num =0;
            while(num<sum){
                String word = s.substring(i+num*len,i+(num+1)*len);
                //判断该单词是否在need中
                if(need.containsKey(word)){ //如果在的话,就把它放进window中
                    window.put(word,window.getOrDefault(word,0)+1);
                    if(need.get(word)<window.get(word)) break;
                }else
                    break;
                num++;
            }
            //判断num是否等于字典中的单词数
            if(num==sum){
                res.add(i);
            }
        }
        return res;
    }
}

每日一题day55:合并相似的物品(力扣2263)

给你两个二维整数数组 items1 和 items2 ,表示两个物品集合。每个数组 items 有以下特质:

items[i] = [valuei, weighti] 其中 valuei 表示第 i 件物品的 价值 ,weighti 表示第 i 件物品的 重量 。
items 中每件物品的价值都是 唯一的 。
请你返回一个二维数组 ret,其中 ret[i] = [valuei, weighti], weighti 是所有价值为 valuei 物品的 重量之和 。

注意:ret 应该按价值 升序 排序后返回。

在这里插入图片描述

集合的使用

class Solution {
    public List<List<Integer>> mergeSimilarItems(int[][] items1, int[][] items2) {
        Map<Integer,Integer> map = new HashMap<>();
        for(int[] v:items1){
            map.put(v[0],map.getOrDefault(v[0],0)+v[1]);
        }
        for(int[] v:items2){
            map.put(v[0],map.getOrDefault(v[0],0)+v[1]);
        }
        List<List<Integer>> res = new ArrayList<>();
        //获取对象的集合
        Set<Map.Entry<Integer,Integer>> entries = map.entrySet();
        for(Map.Entry<Integer,Integer> entry : entries){
            int k = entry.getKey();
            int v = entry.getValue();

            List<Integer> pair = new ArrayList<>();
            pair.add(k);
            pair.add(v);
            res.add(pair);
        }
        Collections.sort(res,(a,b)->a.get(0)-b.get(0));
        return res;
    }
}

每日一题day56:矩阵中的局部最大值(力扣2373)

给你一个大小为 n x n 的整数矩阵 grid 。
生成一个大小为 (n - 2) x (n - 2) 的整数矩阵 maxLocal ,并满足:
maxLocal[i][j] 等于 grid 中以 i + 1 行和 j + 1 列为中心的 3 x 3 矩阵中的 最大值 。
换句话说,我们希望找出 grid 中每个 3 x 3 矩阵中的最大值。
返回生成的矩阵。

class Solution {
    public int[][] largestLocal(int[][] grid) {
        int h = grid.length;  //高度
        int w = grid[0].length; //宽度

        int[][] maxLocal = new int[h-2][w-2];

        for(int i=0;i<h-2;i++){
            for(int j=0;j<w-2;j++){
                //获取i j位置的最大值 
                maxLocal[i][j] = getMax(grid,i,j);
            }
        }
        return maxLocal;
    }
    public int getMax(int[][] grid,int i,int j){
        int max = Integer.MIN_VALUE;
        for(int x=i;x<i+3;x++){
            for(int y=j;y<j+3;y++){
                max = Math.max(max,grid[x][y]);
            }
        }
        return max;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值