每日一题-字符串乘积

[每日一题] (字符串乘积)
Given a list of words, return the maximum numerical product value of two words length, where the two words don’t share any common letters.
For this example, [cat, dog, day, space, telephone]
cat->3 and telephone->9, return 3X9=27

解题思路


这题暂时没什么好的思路,唯一想到可以优化的地方就是可以使用bit manipulation来判断字符是否重复。
可以使用32为二进制数来代表每个单词(假设26个字母), 判断字符是否重复时就直接与运算判断是否为0。
剩下的用Brute Force

Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env python
# -*- coding:utf-8 -*-
words = ["cat", "dog", "day", "space", "telephone"]
class Solution(object):
def wordMul(self, words):
n = len(words)
bit = [0 for i in xrange(n)] # binary number for each word
wl = [len(words[i]) for i in xrange(n)] # length of each word
self.produceBit(words, bit, wl)
maximum = 0
for i in xrange(n-1):
for j in xrange(i, n):
if bit[i] & bit[j] == 0:
maximum = max(maximum, wl[i] * wl[j])
return maximum
def produceBit(self, words, bit, wl):
alpha = "abcdefghijklmnopqrstuvwxyz"
dict = {}
for i in xrange(len(alpha)):
dict[alpha[i]] = i
for i in xrange(len(words)):
for j in xrange(wl[i]):
d = dict[words[i][j]]
bit[i] = bit[i] | 1 << d


每日一题-Trap_Water

[每日一题] (Trapping Rain Water II)
Trapping Rain Water II
Given n x m non-negative integers representing an elevation map 2d where the area of each cell is 1 x 1, compute how much water it is able to trap after raining.

Example
Given 5*4 matrix

[12,13,0,12]
[13,4,13,12]
[13,8,10,12]
[12,13,12,12]
[13,13,13,13]
return 14.

解题思路


使用最小堆
1.对矩形的四周建堆
2.对于堆中每一元素,查探其四邻域中未查探的位置
3.如果h小于当前值,则更新水池容量,并将该位置加入堆中
4.如果h大于等于当前值,则直接加入堆中
最小堆中每次取的元素为当前水池中最短边的长度,如果每次寻找时发现了比最短边低的位置,则可以将水导入(更新水池容量),否则直接将该位置加入到水池中形成新的边缘

笔记

  最小堆的题目的特征(不断找最小),对Python中的最小堆的使用

Python:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env
# -*- coding:utf-8 -*-
import heapq
M = [[12, 13, 0, 12], [13, 4, 13, 12], [13, 8, 10, 12], [12, 13, 12, 12], [13, 13, 13, 13]]
class Solution(object):
def trapWater(self, M):
heap = []
heapq.heapify(heap)
d = [(0, 1), (0, -1), (1, 0), (-1, 0)]
n = len(M)
m = len(M[0])
visit = [[0 for i in xrange(m)] for I in xrange(n)]
res = 0
for i in xrange(n):
for I in xrange(m):
if i == 0 or I == 0 or i == n-1 or I == m-1:
heapq.heappush(heap, (M[i][I], i, I))
visit[i][I] = 1
while heap != []:
this = heapq.heappop(heap)
for i in xrange(4):
h = this[0]
nr = this[1] + d[i][0]
nl = this[2] + d[i][1]
if nr < 0 or nl < 0 or nr >= n or nl >= m:
continue
if visit[nr][nl] == 1:
continue
visit[nr][nl] = 1
tmp = M[nr][nl]
if tmp < h:
res += h - tmp
tmp = h
heapq.heappush(heap, (tmp, nr, nl))
return res


每日一题-二叉树最长连续路径

[每日一题] (二叉树最长连续路径)
在一个二叉树中找出最长连续递增的path,输出path中node的个数。path只能从上到下
Follow-up:path可以从下到上然后从上到下

解题思路


本次的代码没有经过具体测试,仅作讨论用途-.-
原题: 使用递归,每次都计算当前最长路径长度
Follow-up: 使用递归,每次递归的时候计算以当前结点为子树时的最长路径以及与父结点的连续路径。
     具体方法是在每个结点递归调用两次函数,计算左右子树的最长路径长度和连续路径长度,然后比较后返回以该结点为子树最长路径长度和连续路径长度

Python:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/usr/bin/env
# -*- coding:utf-8 -*-
# 原题
class Solution(object):
def longestPath(self, root):
if root == None:
return 0
left = self.recursive(root.left, root.val, 1) # 求左边子树的最大长度
right = self.recursive(root.right, root.val, 1) # 求右边子树的最大长度
return max(left, 1, right)
def recursive(self, node, preVal, tempLength):
if node == None:
return 0
thisLength = tempLength + 1 if node.val == preVal + 1 else 1 # 如果该节点和父节点连续,则当前最大长度为父节点的最大长度+1,否则为1
left = self.recursive(node.left, node.val, thisLength) # 找左子树最大长度
right = self.recursive(node.right, node.val, thisLength) # 找右子树最大长度
return max(left, thisLength, right) # 返回当前节点以后的节点的最大路径长度
# Follow-up
class Solution(object):
def longestPath(self, root):
if root == None:
return 0
left, Lbig, Lsmall= self.recursive(root.left, root.val) # left代表左子树的最长路径长度, Lbig代表root节点左子树中比root大的连续路径长度, Lsmall代表root节点左子树中比root小的连续路径长度
right, Rbig, Rsmall = self.recursive(root.right, root.val) # right代表右子树的最长路径长度, Rbig代表root节点右子树中比root大的连续路径长度, Rsmall代表root节点右子树中比root小的连续路径长度
thisLength = max(left, right, Lbig+1+Rsmall, Rbig+1+Lsmall) # 以当前节点为根的子树的最长路径长度
return thisLength
def recursive(self, node, preVal): # 每次递归计算出以当前node为根的子树的最长路径长度
if root == None:
return 0, 0, 0
left, Lbig, Lsmall = self.recursive(root.left, root.val)
right, Rbig, Rsmall = self.recursive(root.right, root.val)
thisLength = max(left, right, Lbig+1+Rsmall, Rbig+1+Lsmall)
if root.val == preVal + 1:
return thisLength, max(Lbig, Rbig)+1, 0
elif root.val == preVal - 1:
return thisLength, 0, max(Lsmall, Rsmall)+1
else:
return thisLength, 0, 0