首页 > 其他分享 >LeetCode30.串联所有单词的子串

LeetCode30.串联所有单词的子串

时间:2024-10-30 23:17:02浏览次数:7  
标签:子串 hashMap int 单词 words 字符串 strLen LeetCode30 hashMap1

题目链接:30. 串联所有单词的子串 - 力扣(LeetCode)

1.暴力解法(会超时)

由于题目中要判断s中是否有子串符合words,于是可以定义一个hashMap来存储words中的字符串的信息;

定义变量len表示words中字符串的数目,strLen表示每个字符串的长度(words中的字符串长度相同);

遍历s,每次取出长为len * strLen长度的子字符串,再遍历这个子字符串,每次取出子字符串中长为strLen的字符串放到另一个hashMap1中,子字符串遍历完成后,hashMap1中就存储了子字符串中的子串信息,再将这两个map进行比较,判断是否相等,若相等,及说明这两个子串是相同的(顺序不同是可以的),将下标存储到结果集中,继续遍历s,代码如下:

    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> ret = new ArrayList<>();
        int len = words.length;//words中字符串个数
        int strLen = words[0].length();//words中每个字符串的长度
        Map<String, Integer> hashMap = new HashMap<>();
        for (int i = 0; i < len; i++) {
            hashMap.put(words[i], hashMap.getOrDefault(words[i], 0) + 1);
        }
        int sLen = s.length();
        for (int i = 0; i < sLen - len * strLen + 1; i++) {
            boolean flag = true;
            Map<String, Integer> hashMap1 = new HashMap<>();
            for (int j = i; j < len * strLen + i; j += strLen) {
                String subString = s.substring(j, j + strLen);
                hashMap1.put(subString, hashMap1.getOrDefault(subString, 0) + 1);
            }
            if (hashMap.equals(hashMap1)) {
                ret.add(i);
            }
        }
        return ret;
    }

2.滑动窗口

438. 找到字符串中所有字母异位词 - 力扣(LeetCode)中,使用了滑动窗口,由于本题与这一题的思想差不多,于是也可以使用滑动窗口;

和暴力解法一样,需要定义一个hashMap来存储words中的字符串的信息,size表示words中字符串的个数,strLen表示每个字符串的长度;

定义两个指针left和right,两指针均指向0下标位置,再定义一个count表示hashMap1中有效字符串的个数;

每次让right向后移动strLen个单位,将right与right+ strLen之间的子串subString放入hashMap1中,比较hashMap中subString的值与hashMap1中的值,若后者大,表示subString不是有效子串,反之,count++;

让right与left之间的距离大于等于size * strLen时,就移动left,取出left与left + strLen之间的子串subString1,若hashMap1中subString1的值小于等于hashMap中的值,就表示subString1是一个有效的子串,将count--,left向右移动strLen,反之直接将left向右移动strLen,当count与size相等时,就说明这个子串符合条件,将left存入结果集中;

注意:

由于会有以下三种遍历方式,于是right一开始可能并不会从0下标开始,但每size次循环后的遍历过程是一样的,就可以再for循环外再套上一层循环,这个循环执行size次,原理图如下:

    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> ret = new ArrayList<>();
        int size = words.length;//words中字符串个数
        int strLen = words[0].length();//每个字符串的长度
        Map<String, Integer> hashMap = new HashMap<>();
        for (int i = 0; i < size; i++) {//将words中的字符串信息存入hashMap中
            hashMap.put(words[i], hashMap.getOrDefault(words[i], 0) + 1);
        }
        int sLen = s.length();
        int n = 0;
        while (n < strLen) {//循环size次
            Map<String, Integer> hashMap1 = new HashMap<>();
            for (int left = n, right = n, count = 0; right < sLen - strLen + 1; right += strLen) {//count为有效字符串个数
                String subString = s.substring(right, right + strLen);
                hashMap1.put(subString, hashMap1.getOrDefault(subString, 0) + 1);
                if (hashMap1.get(subString) <= hashMap.getOrDefault(subString, 0)) {
                    count++;
                }
                if (right - left >= size * strLen) {
                    String subString1 = s.substring(left, left + strLen);
                    if (hashMap1.get(subString1) <= hashMap.getOrDefault(subString1, 0)) {
                        count--;
                    }
                    hashMap1.put(subString1, hashMap1.get(subString1) - 1);
                    left += strLen;
                }
                if (count == size) {
                    ret.add(left);
                }
            }
            n++;
        }
        return ret;
    }

 希望大家积极交流!!

标签:子串,hashMap,int,单词,words,字符串,strLen,LeetCode30,hashMap1
From: https://blog.csdn.net/2301_79184547/article/details/143376261

相关文章

  • 面试题-单词分割及排序
    题目SortalistofwordsbasedonnumberofcharactersandignoretheasteriskseparatorbetweenthemExampleInput:This*is*a***Hello**World***example**to*demo*your****coding*ability“ExampleOutput:aistoThisdemoyourHelloWorldcodingabilityexamp......
  • 3. 无重复字符的最长子串(中)
    目录题目题解:滑动窗口题目给定一个字符串s,请你找出其中不含有重复字符的最长子串的长度。示例1:输入:s="abcabcbb"输出:3解释:因为无重复字符的最长子串是"abc",所以其长度为3示例2:输入:s="pwwkew"输出:3解释:因为无重复字符的最长子串是"wke",所以......
  • 马拉车算法(回文子串长度)
    #include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintMax=100000;chars[Max*2+5];charstr[Max*2+5];intdp[Max*2+5];voidmc(){intn=strlen(s+1);str[0]='s';intj=1;for(inti=1;i<=n;i++){str[j++]='#&#......
  • 单词render
    参考:E387:render“使成为;使变得;使处于某种状态……”,情感,人生导师,好看视频为何render即是“提供”又是“表达”与“渲染”【词源解词】render给,变化_哔哩哔哩_bilibili1.使具有某种能力。2.把想法经过加工再次表达出来,如:翻译;提交,呈报(把自己的想法加工之后提交、呈报给老......
  • 16课单词
     ジョギングjyoginngu慢跑シャワーsyawa浴びます(浴びる)abiシャワーを浴びます明るい(あかるい) どうやってdouyatteーばん(ー番)bann乗ります(乗る)の電車に乗りますでんしゃ大学前(だいがくまえ)降ります(降りる)お電車を降ります......
  • 【每日一题】LeetCode - 最长回文子串
    在字符串相关的算法题中,寻找最长回文子串是一个经典且富有挑战性的题目。本篇将详细分析并推导两种有效的解决方案:动态规划法和中心扩展法。题目描述给定一个字符串s,我们需要找到s中最长的回文子串。回文是指正着读和反着读都相同的字符串。例如,输入"babad"时,输出可......
  • 代码随想录算法训练营第九天|leetcode151.翻转字符串里的单词、卡码网55.右旋字符串
    1leetcode151.翻转字符串里的单词题目链接:151.反转字符串中的单词-力扣(LeetCode)文章链接:代码随想录视频链接:字符串复杂操作拿捏了!|LeetCode:151.翻转字符串里的单词_哔哩哔哩_bilibili自己的思路:直接将空格去掉,然后分割字符串为列表,在列表中进行翻转,不在字符串内部操作,......
  • 【从零开始的LeetCode-算法】884. 两句话中的不常见单词
    句子 是一串由空格分隔的单词。每个 单词 仅由小写字母组成。如果某个单词在其中一个句子中恰好出现一次,在另一个句子中却 没有出现 ,那么这个单词就是 不常见的 。给你两个 句子 s1 和 s2 ,返回所有 不常用单词 的列表。返回列表中单词可以按 任意顺序 组织。......
  • 八重回文划分法:最多/最少 回文/非回文 子序列/子串 划分
    只考虑常数字符集,所以关于字符集的复杂度都没算进来。最少非回文子串划分答案是\(1\)或\(2\)或者无解,参考CF1951E的题解。时间复杂度:\(\mathcalO(n)\)。最少非回文子序列划分考虑最少非回文子串划分的情况,可以发现答案是\(2\)的情况也不可能划分成\(1\)个子序列,所......
  • 代码随想录算法训练营 | 647. 回文子串,516.最长回文子序列
    647.回文子串题目链接:647.回文子串文档讲解︰代码随想录(programmercarl.com)视频讲解︰回文子串日期:2024-10-19想法:本题精髓在于dp[i][j]表示的是s[i,j]这个子字符串是不是回文的,是Boolean类型,s[i]s[j]不等时,肯定不回文;s[i]s[j]相等时,开始看ij的大小,ij大小相等那么表示单个字......