leetcode: substring-with-concatenation-of-all-words

题目描述:

您将获得一个字符串 S 和一个单词列表 L,它们的长度都相同。
找到 S 中子串的所有起始索引,它是 L 中每个单词的串联,只有一次,没有任何插入字符。

例如,给定:
S:“barfoothefoobarman”
L:[“foo”,“bar”]

你应该返回索引:[0,9]。
(顺序无所谓)。

解题思路:

  1. 理解题意最重要,题目的意思就是说,找到 S 中的字串 sunString,使其包含所有的 L 中的字符串,其中 L 中的字符串顺序无所谓(看到这里,你首先应该想到的是 HashMap )
  2. 对于这题,我首先想到的是将 L 中的字符串利用全排列组成一整个字符串,然后再在 S 中找
  3. 然后发现这样工作量特别大
  4. 这里采用遍历 S 字符串,截取固定长度的方法,具体的思路如下
  5. 将 L 中的字符串用 hashmap 来存储,字符串作为键,次数作为值
  6. 因为这里 L 中的字符串长度固定,按顺序从 S 中取出固定的长度字符串,并判断是否存在与 hashmap 中,这里同时也建立一个临时 hashmap,取名为 temp, 用来防止单个字符串多次出现的情况

代码如下:

 public ArrayList<Integer> findSubstring(String S, String[] L) {
        ArrayList<Integer> list = new ArrayList<>();
        if(S.isEmpty() || L == null || L.length == 0)
            return list;

        int n = L.length;
        int size = L[0].length();
        HashMap<String, Integer> wordCnt = new HashMap<>();
	
	// 将数组里的字符串存储到 hashmap 中
        for(String item : L){
            if(wordCnt.containsKey(item)){
                int value = wordCnt.get(item) + 1;
                wordCnt.put(item, value);
            }else
            {
                wordCnt.put(item, 1);
            }
        }

	// 每次取出固定长度的字符串
        for(int i = 0; i <= (int)S.length() - n * size; i++){
            HashMap<String, Integer> strcnt = new HashMap<>();
            int j = 0;
			
	   // 如该字串包含所有的数组内的字符串,那么它肯定连续遍历了 n 次
            for(j = 0; j < n; j++){
                String temp = S.substring(i + j * size,i + (j + 1) * size);
                if(!wordCnt.containsKey(temp))
                    break;
		
		// 单个字符串可能出现多次,所以这里为了便于比较,再开辟一个 hashmap,来比较次数
                if(strcnt.containsKey(temp)){
                    int value = strcnt.get(temp) + 1;
                    strcnt.put(temp,value);
                }else{
                    strcnt.put(temp,1);
                }

                if(strcnt.get(temp) > wordCnt.get(temp))
                    break;
            }

            if(j == n) list.add(i);
        }
        return list;
    }

转载于:https://my.oschina.net/happywe/blog/3075022

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值