【每日一题见微知著】字符串匹配问题-串联所有单词的子串-Hard

这篇博客介绍了LeetCode中30题的解法,探讨如何找到字符串中能完全匹配所有给定相同长度单词的子串。解题策略包括使用数组记录单词出现次数,借助HashMap快速查找,并通过遍历判断子串是否符合要求。
摘要由CSDN通过智能技术生成

⭐️寒假新坑——代码之狐的每日做题笔记

30. 串联所有单词的子串-Hard

题目描述:

给定一个字符串 s 和一些 长度相同 的单词 words **。**找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。

注意子串要与 words 中的单词完全匹配,中间不能有其他字符 ,但不需要考虑 words 中单词串联的顺序。

在这里插入图片描述

在这里插入图片描述

解题思路:
  • 使用一个数组count[][]保存words数组中每种字符串出现的次数,并利用一个HashMap保存字符串与其在count中的位置对应,比如<“word”,0>表示"word"字符串在words中出现次数保存在count[0]=2中,出现了两次。

  • 历遍一次s,判定每个s中的长度为word.length的子字符串是否是words中的字符,使用HashMap快速查找其在count中的位置,并使用一个数组indexS保存,如果不是保存-1;

  • 再次历遍indexS数组,每次查找i、i+word.length、i+2 * word.length、…、i+(words.length-1)* word.length,统计其是否有对应的words,并记录在数组judge中,如果出现-1(表示,该子字符串存在不能被words匹配的片段),立即退出;统计完成后,匹配是否与count对应,如果对应,则记录一次结果

代码实现:
class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        int wL=words[0].length();
        int sL=s.length();
        int wN=words.length;

        Map<String,Integer> map=new HashMap<>();
        for(String i:words){
            map.put(i,map.getOrDefault(i,0)+1);
        }

        int[] count=new int[map.size()];
        int countI=0;
        for(Map.Entry<String,Integer> e:map.entrySet()){
            count[countI]=e.getValue();
            map.put(e.getKey(),countI);
            countI++;
        }
        int indexSL=sL-wL+1;
        int[] indexS=new int[indexSL];

        for(int i=0;i<indexSL;i++){
            indexS[i]=map.getOrDefault(s.substring(i,i+wL),-1);
        }
        List<Integer> ans=new ArrayList<>();
        for(int i=0;i<indexSL;i++){
            int[] judge=new int[count.length];
            int iR=i+(wN-1)*wL;
            if(iR>=indexSL){
                break;
            }
            for(int k=i;k<=iR;k+=wL){
                if(indexS[k]==-1){
                    break;
                }
                else{
                    judge[indexS[k]]++;
                }
            }
            boolean equal=true;
            for(int z=0;z<count.length;z++){
                if(judge[z]!=count[z]){
                    equal=false;
                    break;
                }
            }
            if(equal){
                ans.add(i);
            }
        }
        return ans;
    }
}

结尾

题目来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems

⭐️关注作者,带你刷题,从简单的算法题了解最常用的算法技能(寒假每日一题)
⭐️关注作者刷题——简单到进阶,让你不知不觉成为无情的刷题机器,有问题请私信

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码之狐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值