472. Concatenated Words
和这题类似的 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
548. Split Array with Equal Sum
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 求交集 | 求并集
862. Shortest Subarray with Sum at Least K
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
315. Count of Smaller Numbers After Self
we will define the tree node as follows, where val is the node value and cnt is the
total number of elements in the subtree rooted at current node that are smaller than or equal to val:
class Node:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
self.count = 1
class Solution(object): # O(nlogn)
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): # O(n)
res.append(self.insert_node(nums[i], root)) # O(logn)
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) # 这里不给newNode.count赋值,因为如果有一个新的节点进来count数的时候会加这个newNode的父节点的root.count,所以这个newNode不要再加上前面root.count
# 会
break
root = root.right
return count