3. Longest Substring Without Repeating Characters
可以用hash,即dic{}做,也可以用two pointers, window方法做。
- Hash: 如果元素e在usedchar{}里,并且
start <= usedchar[e]
, 就对start进行更新:start = usedchar[e] + 1
, 否则就更新maxlen:maxlen = max(maxlen, i - start + 1)
, 因为start是从0开始的,要计算长度所以要加1,遍历一遍之后返回maxlen。注意这里循环用的是enumerate, 比单纯使用for循环更方便一些 - Window: 使left, right都从0开始, 循环条件是
while right < len(s)
, 如果s[right] 不在s[left:right]这个窗口里,就将right和maxlen更新:right += 1, maxlen = max(maxlen, right - left)
, 反正如果s[right]存在窗口里,就代表出现了重复元素,就将left向右挪一位,直到没有重复元素为止。 - 复杂度均为O(n)
11. Container With Most Water
同样用two pointer和夹逼的方法,结合贪心算法greedy algorithm,left从0开始,right从len(height)-1开始,初始化maxwater也为0. 循环判断条件:while left < right:
先对maxwater进行更新
maxwater = max(maxwater, (right - left) * min(height[left], height[right]))
, 再判断left和right的大小关系,如果left小于right,就右移left,否则就左移right。
36. Valid Sudoku
这道题用到的是set, 不是hash,
a = [11,22,33,44,11,22], b = set(a) b->set([33, 11, 44, 22])
这题用到set可以去掉重复元素这个性质。对每个不为空的数字进行记录,记录所在行,所在列,以及所在的每个小board(一共有9个小board)。
existed += [(i, e),(e, j),(i/3, j/3, e)]
e是不为空的元素,i是行,j是列。(i,e)表示第i行的e元素,(e, j)表示第j列的e元素,(i/3, j/3, e)表示e元素处在第几个小board里。遍历一遍后,对existed这个列表进行set操作,看经过set操作后的列表长度与原来的长度是否相同,若相同,就证明没有重复元素,若不同,就证明有相同元素,invalid
why (c, j) but (i, c)? (the order of c, j, and i)?
To distinguish rows and columns, for example ('4', 4) and (4, '4').
49. Group Anagrams
将anagrams分组,anagram就是字母组成相同的word。思路是先初始化一个值类型为List的hash table, 然后对数组中的每个word进行sorted(),这样之后每个word会被拆成'a', 'e', 't'这种形式,再用s = ''.join(sorted(word))
将每个字母无缝连接起来。这样,每一类的anagrams都会得到相同的一个结果。用这个结果作为hash里边的key, 对每个word都进行dic[s].append(word)
. **因为每个anagram得到相同的s,所以会被append进同一个key对应的list里。这样就完成了分类。
接下来就是获得这个分类。对dic里的每个value,如果value的长度大于等于1,就将这个value append到res里。
**需要注意的是: [""]长度为1,不为0. append和extend(参数只能是List类型)的区别