LeetCode—substring-with-concatenation-of-all-words(找给出子串数组组成的所有子串的位置)—java

138 篇文章 0 订阅
132 篇文章 0 订阅

题目描述

You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.i

For example, given:
S:"barfoothefoobarman"
L:["foo", "bar"]

You should return the indices:[0,9].
(order does not matter).

思路解析

  • 首先使用HashMap把给出的字符串数组都存起来,使用String作为key,即代码中dict
  • 然后因为每个子串的长度相等,所以遍历过程只需要子串长度len次,这是外层循环,因为遍历每个i时都是检查i到i+len的子串是不是在dict里面,然后还会检查i+len到i+2len是不是符合,所以需要len次外循环
  • 然后里面的循环是判断初始i,,用j表示,开始以后的每个j+len,j+2len是不是符合dict的key,使用cur表示目前符合的字符串,临时存储
  • 注意cur中每个key的数量不能大于dict中的key对应的数目,这样保证出现的次数是符合条件的,给的数组中有几个key,你出现最多也只能有几次。
  • count记录数组给的字符串一共出现多少个,是用来判断是不是等于数组长度,如果等于,说明数组中的都找到了,符合条件,加入res中,此时要更新index的值为跳到下一个word,所以从index到index+len的这个word就少一个了,count就减一了,cur里面这个word也要减一了。

代码

import java.util.*;
public class Solution {
    public ArrayList<Integer> findSubstring(String S, String[] L) {
        ArrayList<Integer> res = new ArrayList<Integer>();
        if(S==null||L==null||S.length()==0||L.length==0)
            return res;
        HashMap<String,Integer> dict = new HashMap<String,Integer>();
        int len = L[0].length();
        for(String word :L){
            if(!dict.containsKey(word))
                dict.put(word,1);
            else
                dict.put(word,dict.get(word)+1);
        }
        for(int i=0;i<len;i++){
            HashMap<String,Integer> cur = new HashMap<String,Integer>();
            int count =0;
            int index = i;
            for(int j=i;j<=S.length()-len;j+=len){
                String curword = S.substring(j,j+len);
                if(!dict.containsKey(curword)){
                    cur.clear();
                    count =0;
                    index = j+len;
                }else{
                    if(!cur.containsKey(curword)){
                        cur.put(curword,1);
                    }else{
                        cur.put(curword,cur.get(curword)+1);
                    }
                    if(cur.get(curword)<=dict.get(curword)){
                        count++;
                    }else{
                        String temp = S.substring(index,index+len);
                        cur.put(temp,cur.get(temp)-1);
                        index = index+len;
                    }
                    if(count==L.length){
                        res.add(index);
                        String temp = S.substring(index,index+len);
                        cur.put(temp,cur.get(temp)-1);
                        index = index +len;
                        count--;
                    }
                }
            }
        }
        Collections.sort(res);
        return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值