这两道题目都很巧妙的应用了哈希算法,可以作为哈希算法的应用讲解,后面介绍哈希的时候就不再做题了哈。
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.
题目解析
该题的思路是这样的:
- 江words做成字典,可以理解为编码;
- 匹配的过程就是,new_map控制与words的匹配过程,直到new_map与word_map相等,matched == len(words),此时start的位置是我们需要的结果,start+total 就是与words吻合的部分。
- 优化思路,外层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()]