4.4.2 python 字符串双指针/哈希算法2 —— Substring with Concatenation of All Words & Group Anagrams

这两道题目都很巧妙的应用了哈希算法,可以作为哈希算法的应用讲解,后面介绍哈希的时候就不再做题了哈。

30. Substring with Concatenation of All Words

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.
Example 1:
Input:

  s = "barfoothefoobarman",
  words = ["foo","bar"]

Output: [0,9]
Explanation: Substrings starting at index 0 and 9 are “barfoor” and “foobar” respectively.
The output order does not matter, returning [9,0] is fine too.

题目解析

该题的思路是这样的:

  1. 江words做成字典,可以理解为编码;
  2. 匹配的过程就是,new_map控制与words的匹配过程,直到new_map与word_map相等,matched == len(words),此时start的位置是我们需要的结果,start+total 就是与words吻合的部分。
  3. 优化思路,外层for循环只有word_len长度,,因此性能不错。充分利用new_map,从头走到尾,不回溯,用start 记录起始索引,当超过长度时,start 后移,new_map减少。
class Solution:   
    def findSubstring(self, s, words):
        """
        :type s: str
        :type words: List[str]
        :rtype: List[int]
        """
        from collections import Counter
        if not s or not words or not words[0]: return []
        ret = []
        word_len = len(words[0])
        word_map = dict(Counter(words))
        total = len(words) * word_len
        for i in range(word_len):
            new_map = {}
            matched = 0
            start = i
            for j in range(i, len(s) - word_len + 1, word_len):
                if j - start >= total:
                    old_word = s[start:start + word_len]
                    if old_word in new_map:
                        new_map[old_word] -= 1
                        if new_map[old_word] < word_map[old_word]:
                            matched -= 1
                    start += word_len
                word = s[j: j + word_len]
                if word in word_map:    # 与word_map匹配的过程
                    new_map[word] = new_map.get(word, 0) + 1
                    if new_map[word] <= word_map[word]:
                        matched += 1
                    if matched == len(words):
                        ret.append(start)
        return ret

49. Group Anagrams

Given an array of strings, group anagrams together.
Example:
Input: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
Output:
[
[“ate”,“eat”,“tea”],
[“nat”,“tan”],
[“bat”]
]
Note:
All inputs will be in lowercase.
The order of your output does not matter.

题目解析

题目不难,下面的解法巧妙的构建了字典的key,text = "".join(sorted(s)),即所有字母排序后拼接。最后列表推导式取出字典的value,可谓非常简洁奇妙的方法。

class Solution:
    def groupAnagrams(self, strs):
        """
        :type strs: List[str]
        :rtype: List[List[str]]
        """
        dict_ = {}
        for s in strs:
            text = "".join(sorted(s))
            dict_[text] = dict_.get(text, [])
            dict_[text].append(s)          
        return [ele for ele in dict_.values()]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值