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

34 篇文章 0 订阅

优化前的代码由LeetCode大佬写,优化后是我写的:

优化后:优化思路

例如s="efabcdabcdab", words=["ab","cd","ab"], 初始map={<"ab", 2>, <"cd", 1>}, 初始放置subMap={<"ef", 1>, <"ab", 1>,<"cd", 1>};

map是否与subMap相等,不等,则移掉"ef", 加入"ab",  "efabcdabcdab"----》"efabcdabcdab";

map是否与subMap相等,此时相等,将2加入list, list=[2], 则移掉"ab", 加入"cd",  "efabcdabcdab"----》"efabcdabcdab";

map是否与subMap相等,不等,则减少掉1个"cd", 加入"ab","efabcdabcdab"----》"efabcdabcdab";

map是否与subMap相等,此时相等,将6加入list, list=[2,6], 结束index=0的循环,

下次循环index=1,subMap依次为蓝色部分,"efabcdabcdab"----》"efabcdabcdab"----》"efabcdabcdab",都不等

index=2=一个档次的长度,跳出循环。

最终返回list=[2,6]

public static List<Integer> findSubstring(String s, String[] words) {
        List<Integer> list = new ArrayList<>();
        if(s==null||s.length()==0||words==null||words.length==0) return list;
        int wordLen = words[0].length(), wordNum = words.length, patternLen = wordLen*wordNum;
        if(patternLen>s.length()){
            return list;
        }
        Map<String, Integer> map = new HashMap<>();
        for(int i = 0; i < wordNum; i++){
            map.put(words[i], map.getOrDefault(words[i],0)+1);
        }
        for(int index = 0; index < wordLen; index++) {//为了减少工作量之前的循环其实重复做了put操作
        	HashMap<String, Integer> subMap = new HashMap<>();
        	String temp;
        	int j = index;
        	boolean flag = true;
        	for(; j < s.length()-wordLen+1&&j<patternLen+index; j=j+wordLen){//放置一开始subMap
                temp = s.substring(j, j+wordLen);
                subMap.put(temp, subMap.getOrDefault(temp, 0)+1);
            }       	
        	j = index;
        	for(; j < s.length()-patternLen;j = j + wordLen) {
        		if(subMap.equals(map)) {
        			list.add(j);
        		}
        		temp = s.substring(j, j+wordLen);
        		Integer num =subMap.get(temp);
        		if(num==null||num==1) {
        			subMap.remove(temp);
        		}else {
        			subMap.put(temp, subMap.get(temp)-1);
        		}       		
	    		if(j+patternLen+wordLen > s.length()){
	               break;
	            }
        		temp = s.substring(j+patternLen, j+patternLen+wordLen);
        		subMap.put(temp, subMap.getOrDefault(temp, 0)+1);
        	}
        	if(subMap.equals(map)) {
    			list.add(j);
    		}
        }       
        return list;
    }

优化前

    public static List<Integer> findSubstring(String s, String[] words) {
        List<Integer> res = new ArrayList<>();
        if (s == null || s.length() == 0 || words == null || words.length == 0) return res;
        HashMap<String, Integer> map = new HashMap<>();
        int one_word = words[0].length(), word_num = words.length, all_len = one_word * word_num;
        for (String word : words) {
            map.put(word, map.getOrDefault(word, 0) + 1);//每个单词 在单词 里面的个数
        }
        for (int i = 0; i < s.length() - all_len + 1; i++) {
            String tmp = s.substring(i, i + all_len); //所有的单词组合成的字符串的长度
            HashMap<String, Integer> tmp_map = new HashMap<>();
            for (int j = 0; j < all_len; j += one_word) {
                String w = tmp.substring(j, j + one_word);
                tmp_map.put(w, tmp_map.getOrDefault(w, 0) + 1);
            }
            if (map.equals(tmp_map)) res.add(i);//相同的时候hashmap会相等,因为hashmap就是根据hashcode实现的
        }
        return res;       
    }

//作者:powcai
//链接:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/solution/chuan-lian-suo-you-dan-ci-de-zi-chuan-by-powcai/
//来源:力扣(LeetCode)
//著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处。 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值