LeetCode 30.串联所有单词的字串

1、题目描述

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

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

  • 例如,如果 words = ["ab","cd","ef"], 那么 "abcdef", "abefcd""cdabef", "cdefab""efabcd", 和 "efcdab" 都是串联子串。 "acdbef" 不是串联子串,因为他不是任何 words 排列的连接。

返回所有串联子串在 s 中的开始索引。你可以以 任意顺序 返回答案。

2、算法思路

         异位词的长度是和p的长度是固定的。是连续的窗口,所以使用滑动窗口来解决,但是是固定大小的窗口。

        并且使用count来记录窗口中的字母的种类和个数。当count中记录的种类和个数和p的种类和个数一样就可以更新结果。可以把s中的每len = word[0].length的长度看成是一个字符。

3、算法流程

        因为条件中words 中所有字符串 长度相同指出,所以s中长度是每word[0].length是一个字符,把长度是word[0].length看成是一个字符。⽆⾮就是之前处理的对象是⼀个⼀个的字符,我们这⾥处理的对象是⼀个⼀个的单词。具体我们可以参考LeetCode 438.找到字符串中所有字母异位词-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/EdgeAI/article/details/145023585?spm=1001.2014.3001.5501

4、算法代码

ight+len<=s.length(),需要这一句。是因为判断不能超过索引,需要等于是因为我们是先判断了+len。在第438题,没有这样写是因为麻烦,当然这个写也是对的。

438. 找到字符串中所有字母异位词 - 力扣(LeetCode)

class Solution {
    public  List<Integer> findSubstring(String s, String[] words){
         List<Integer> ret = new ArrayList<Integer>();
        Map<String ,Integer> hash1 = new HashMap<String,Integer>();
        for (String str:words) hash1.put(str,hash1.getOrDefault(str,0)+1);
        int len = words[0].length(),m = words.length;
        for (int i=0;i<len;i++){
            Map<String ,Integer> hash2 = new HashMap<String ,Integer>();
            for (int left = i,right = i,count = 0;right+len<=s.length();right+=len){
                //进窗口
                String into = s.substring(right,right+len);
                hash2.put(into,hash2.getOrDefault(into,0)+1);
                if (hash2.get(into) <= hash1.getOrDefault(into,0)) count++;
                //判断
                if (right-left+1 > len *m)
                {
                    //出窗口
                    String out = s.substring(left,left+len);
                    if (hash2.get(out) <= hash1.getOrDefault(out,0)){//如果是有效字符就count--
                        count--;
                    }
                    hash2.put(out,hash2.get(out)-1);//减去字符的hash2
                    left+=len;

                }
                //更新结果
                if (count == m) ret.add(left);
            }
        }
        return ret;
    }
}

5、运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值