春招打卡d12n20-leetcode刷题30串联所有单词的子串

142 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

leetcode刷题30串联所有单词的子串

前文

本文为leetcode字符串类型题目,题目序号为30,主要考察对于字符串的处理效率。

题目信息

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

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

解题思路

根据题目信息,想要在目标字符串中找到我们需要的满足条件的字符串,主要采用map来解决这一问题。预先将目标数组装进map中保存。而与此同时,对于原字符串进行滑动遍历,将窗口设置为数组中所有字符串长度之和。向前遍历的过程中,将对应的字符串转为map,并与之前的map进行比较确定是否存储结果数组。按此方式遍历完成,考虑一些特殊情况,即可得到最终的目标结果。

解题代码

public List<Integer> findSubstring(String s, String[] words) {
    List<Integer> result = new ArrayList<>();
    if(words.length == 0){
        return result;
    }
    Map<String,Integer> map = new HashMap<>();
    int length = 0;
    int itemLength = -1;
    for (int i = 0; i < words.length; i++) {
        map.put(words[i],map.getOrDefault(words[i],0) + 1);
        length += words[i].length();
        itemLength = words[i].length();
    }
    if(length > s.length()){
        return result;
    }
    for (int i = 0; i <= s.length() - length; i++) {
        String str = s.substring(i,i + length);
        if(str.length() != length){
            break;
        }
        Map<String,Integer> itemMap = new HashMap<>();
        for (int j = 0; j < length/itemLength; j++) {
            itemMap.put(str.substring(itemLength * j,itemLength * (j + 1)),itemMap.getOrDefault(str.substring(itemLength * j,itemLength * (j + 1)),0) + 1);
        }
        boolean ok = true;
        for (int j = 0; j < words.length; j++) {
            if(itemMap.containsKey(words[j]) && itemMap.get(words[j]).equals(map.get(words[j]))){
                continue;
            }else{
                ok = false;
                break;
            }
        }
        if(ok){
            result.add(i);
        }
    }
    return result;
}

后记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。