leetcode刷题笔记-难题整理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Sengo_GWU/article/details/84642572

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

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
                

 

猜你喜欢

转载自blog.csdn.net/Sengo_GWU/article/details/84642572