和这题类似的 139. Word Break https://leetcode.com/problems/word-break/description/
解法一DPpython超时,但是JAVA解法可以通过。也是139题的解法延伸。
class Solution(object):
def findAllConcatenatedWordsInADict(self, words):
words = sorted(words, cmp=lambda a, b: cmp(len(a), len(b)))
re = []
for i, w in enumerate(words):
# compare every words with every other words before it. 前面的长度比它小,只需要比较长度比它小的
if not w: continue # 注意要过滤空字符串
dp = [False] * (len(w) + 1)
dp[0] = True
for j in xrange(1, len(w)+1):
for cmpidx in xrange(i):
cmpWord = words[cmpidx]
if len(cmpWord) == len(w): break
if dp[j-len(cmpWord)] and w[j-len(cmpWord):j] == cmpWord:
dp[j] = True
break
if dp[len(w)]: re.append(w)
return re
下面一种是通过的。
class Solution(object):
def findAllConcatenatedWordsInADict(self, words):
words = set(words)
res = []
for w in words:
if not w: continue
stack = [0]
seen = {0}
n = len(w)
while stack:
i = stack.pop()
if i == n:
res.append(w)
break
for j in xrange(i+1, n+1): # n+1 因为下面的j是不包括的,j要可以达到n
# the word must be broken but not a complete one
if j not in seen and w[i: j] in words and not(i==0 and j==len(w)):
stack.append(j)
seen.add(j)
return res
i,j,k 不要拆成 4部分 sub1 i sub2 j sub3 k sub4. 我们只要从j拆成2部分, sub1=sub2 = sub3 = sub4就行了
class Solution(object):
def splitArray(self, nums):
# i, j,k 不要,拆分成4部分,要求4个sub 的sum equal
n = len(nums)
s = [0] * (n+1) # s[i] = sum nums[0] to nums[i-1]
for i in xrange(n): s[i+1] = s[i] + nums[i]
def check(l, r):
# 相当于不要nums[m] 的左右两边的sum 相同
return set(s[m] - s[l] for m in range(l + 1, r + 1) if s[m] - s[l] == s[r + 1] - s[m + 1])
return any(check(0, j-1) & check(j+1, n-1) for j in xrange(n)) # &对于set 求交集 | 求并集
https://leetcode.com/problems/minimum-size-subarray-sum/description/ 这题的升级版,加入负数。
保持queue里面B的index对应的值是保持递增的。B[i] 是前a[0]到a[i-1]的sum。见下图。所以我们要while 一直让B【最后】-B【最前】 如果相减>=k。
class Solution(object):
def shortestSubarray(self, A, K):
N = len(A)
B = [0] * (N+1) # sum
for i in xrange(N): B[i+1] = B[i] + A[i]
re = N + 1
q = []
for i in xrange(N+1): # 要加1
while q and B[i] - B[q[0]] >= K: re = min(re, i - q.pop(0))
while q and B[i] <= B[q[-1]]: q.pop()
q.append(i)
return re if re <= N else -1
count的值是指当前node 和它左子树 Node节点的数量
class Node:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
self.count = 1
class Solution(object):
def countSmaller(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
if not nums:
return []
root = Node(nums[-1])
res = [0] # 最后一个肯定是0
for i in xrange(len(nums)-2, -1, -1):
res.append(self.insert_node(nums[i], root))
return res[::-1]
def insert_node(self, val, root):
count = 0
while True:
if val <= root.val:
root.count += 1
if not root.left:
root.left = Node(val)
break # break了 root还是上一个值,不是当前的val
root = root.left
else:
count += root.count
if not root.right:
root.right = Node(val)
break
root = root.right
return count