leetcode刷题笔记-难题整理

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
                

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值