leetCode练习(30)

题目:Substring with Concatenation of All Words

难度:hard

问题描述:

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

For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]

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

解题思路:题意比较难以理解,简单说,就是让words里的单词每个都(可以不分顺序)出现在索引之后有且只有一次。如果words里有【a,a】,那就是找含有aa的子串,如果是【b,a,a】,就是找 aab、aba、baa的子串索引。

一开始,我的思路是先构造一个hashmap,保存words里所有的单词出现的次数。然后找到所有单词在母串中的索引,然后从每个索引开始检测是否符合要求。具体代码如下:

public class h_30_SubstringWithConcatenationOfAllWords {
	public  List
   
   
    
     findSubstring(String s, String[] words) {
		ArrayList
    
    
     
      list=new ArrayList<>();
		ArrayList
     
     
      
       index=new ArrayList<>();
		if(s==null||words==null)		return list;
		if(words[0].equals(""))			return list;
		//文本长度
		int textlen=s.length();
		//单词长度
		int len=words[0].length();
		String temp;
		int inttemp;
		//初始化Hashmap
		HashMap
      
      
       
        map=getHashMap(words);
		//参照表
//		System.out.println("参照表");
		HashMap
       
       
         hm=getHashMap(words); clearMap(hm,words); for(String w:words){ hm.put(w, hm.get(w)+1); // System.out.println("word="+w+" value="+hm.get(w)); } //找到每个单词出现的位置 HashMap 
        
          word=new HashMap 
         
           (); for(int i=0;i 
          
            textlen){ continue; } //提取要判断的字符串 temp=s.substring(inttemp, inttemp+words.length*len); //判断temp里是不是不重复地包含了所有字符串 if(isAllcontained(map,hm,temp,words)){ list.add(inttemp); } clearMap(map,words); } return list; } public HashMap 
           
             getHashMap(String[] words){ HashMap 
            
              map=new HashMap<>(); for(int i=0;i 
             
               map,String[] words){ for(int i=0;i 
              
                map,HashMap 
               
                 hm,String s,String[] words){ // System.out.println("str="+s); int len=words[0].length(); String temp; for(int i=0;i 
                
                  list=s.findSubstring("111hahzzpzzphah111",words); System.out.println("--------------"); for(int i=0;i 
                  
                 
                
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   

但是,运行显示超时,经过分析,我觉得是对hashmap的操作才复杂,用到了多个表进行对比,为此,我重新参考了NearXDJ的文章,觉得去除“找到所有单词在母串中的索引”这一步骤,直接对母串从I=0开始遍历检查是否满足条件。不过运行时间依然不通过~经过优化,我将循环中的String的构造拿了出来,这才使时间勉强通过~

具体代码如下:

public class Solution {
   public  List
    
    
     
      findSubstring(String s, String[] words) {
        String temp=new String();
		ArrayList
     
     
      
       res=new ArrayList
      
      
       
       ();
		if(s.equals("")||words==null){	//为空时
			return res;
		}
		int slen=s.length();				//母串长度
		int wordlen=words[0].length();	//子串长度
		int wordCount=words.length;		//单词长度
		int sublen=wordlen*wordCount;	//每次需要从母串中拿来进行匹配的子串的长度
		HashMap
       
       
        
         mywords=new HashMap
        
        
          (); int i,j,k; for(i=0;i 
         
           tempMap=new HashMap 
          
            (mywords); count=0; int subCount=i+sublen; //临时保存母串中需要拿出来匹配的长度 k=i; while(k 
           
             0){ tempMap.put(temp, tempMap.get(temp)-1);//将用过的单词剔除 k=k+wordlen; count++; }else{ //虽然找到,但是多余了,也要剔除 i++; break; } } if(count==wordCount){ res.add(i); tempMap.clear(); i++; } } } return res; } } 
            
           
          
        
       
       
      
      
     
     
    
    

自己的代码在所有的submit中只处于中下的运行时间,觉得还有很多可以优化的地方,不过本人技术很差,故将代码奉上,希望大家提出宝贵的意见哈!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值