python leetcode 211-220

# 212 太难了抄的官方
class Solution:
    def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
        WORD_KEY = '$'
        trie = {}
        for word in words:
            node = trie
            for letter in word:
                # retrieve the next node; If not found, create a empty node.
                node = node.setdefault(letter, {})
            # mark the existence of a word in trie node
            node[WORD_KEY] = word
        rowNum = len(board)
        colNum = len(board[0])
        matchedWords = []
        def backtracking(row, col, parent):    
            letter = board[row][col]
            currNode = parent[letter]
            # check if we find a match of word
            word_match = currNode.pop(WORD_KEY, False)
            if word_match:
                # also we removed the matched word to avoid duplicates,
                #   as well as avoiding using set() for results.
                matchedWords.append(word_match)
            # Before the EXPLORATION, mark the cell as visited 
            board[row][col] = '#'
            # Explore the neighbors in 4 directions, i.e. up, right, down, left
            for (rowOffset, colOffset) in [(-1, 0), (0, 1), (1, 0), (0, -1)]:
                newRow, newCol = row + rowOffset, col + colOffset     
                if newRow < 0 or newRow >= rowNum or newCol < 0 or newCol >= colNum:
                    continue
                if not board[newRow][newCol] in currNode:
                    continue
                backtracking(newRow, newCol, currNode)
        
            # End of EXPLORATION, we restore the cell
            board[row][col] = letter
        
            # Optimization: incrementally remove the matched leaf node in Trie.
            if not currNode:
                parent.pop(letter)

        for row in range(rowNum):
            for col in range(colNum):
                # starting from each of the cells
                if board[row][col] in trie:
                    backtracking(row, col, trie)
        
        return matchedWords 
# 213
class Solution:
    def rob(self, nums: List[int]) -> int:
        if not nums:
            return 0 
        if len(nums) == 1:
            return nums[0]
        def helper(nums):
            if not nums:
                return 0 
            if len(nums) == 1:
                return nums[0]
            dp = [nums[0] , max(nums[0] , nums[1])]
            for i in range(2 , len(nums)):
                dp.append(max((dp[0] + nums[i]) , dp[1]))
                dp.pop(0)
            return dp[-1]
        return max(helper(nums[1:]) , helper(nums[:-1]))
# 214
class Solution:
    def shortestPalindrome(self, s: str) -> str:
       r = s[::-1]
       for i in range(len(s) + 1):
           if s.startswith(r[i:]):
               return r[:i] + s
# 215
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        nums.sort()
        return nums[-k]
# 216
class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        res = []
        def helper(k , n , start , tmp):
            if k == 0 and n == 0 and tmp not in res:
                res.append(tmp)
                return
            for i in range(start , 10):
                helper(k - 1 , n - i , i + 1 , tmp + [i])
        helper(k , n , 1 , [])
        return res
# 217
class Solution:
    def containsDuplicate(self, nums):
        n1 = len(nums)
        n2 = len(set(nums))
        if n1 == n2:
            return False
        return True
# 218
class Solution:
    def getSkyline(self, buildings: List[List[int]]) -> List[List[int]]:
        if not buildings: return []
        if len(buildings) == 1:
            return [[buildings[0][0], buildings[0][2]], [buildings[0][1], 0]]
        mid = len(buildings) // 2
        left = self.getSkyline(buildings[:mid])
        right = self.getSkyline(buildings[mid:])
        return self.merge(left, right)
    def merge(self, left, right):
        lh = rh = 0
        l = r = 0
        res = []
        while l < len(left) and r < len(right):
            if left[l][0] < right[r][0]:
                cp = [left[l][0], max(left[l][1], rh)]
                lh = left[l][1]
                l += 1
            elif left[l][0] > right[r][0]:
                cp = [right[r][0], max(right[r][1], lh)]
                rh = right[r][1]
                r += 1
            else:
                cp = [left[l][0], max(left[l][1], right[r][1])]
                lh = left[l][1]
                rh = right[r][1]
                l += 1
                r += 1
            if len(res) == 0 or res[-1][1] != cp[1]:
                res.append(cp)
        res.extend(left[l:] or right[r:])
        return res
# 219
class Solution:
    def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
        if len(nums) == len(set(nums)):
            return False
        dict1 = {}
        for i in range(len(nums)):
            if nums[i] not in dict1:
                dict1[nums[i]] = i
            else:
                if i - dict1[nums[i]] <= k:
                    return True
                dict1[nums[i]] = i
        return False
# 220 (线性 可能会超时)
class Solution:
    def containsNearbyAlmostDuplicate(self, A: List[int], k: int, t: int) -> bool:
        if t < 0: return False
        if not t:
            seen = {}
            for i, a in enumerate(A):
                if a in seen and i-seen[a] <= k:
                    return True
                seen[a] = i
            return False
        n = len(A)
        for i in range(n):
            for j in range(i+1, min(i+k+1, n)):
                if abs(A[i] - A[j]) <= t:
                    return True
        return False
(桶排序 o(n)能通过)
class Solution:
    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:
        if t < 0 or k < 0:
            return False
        all_buckets = {}
        bucket_size = t + 1                     # 桶的大小设成t+1更加方便
        for i in range(len(nums)):
            bucket_num = nums[i] // bucket_size # 放入哪个桶
            if bucket_num in all_buckets:       # 桶中已经有元素了
                return True
            all_buckets[bucket_num] = nums[i]   # 把nums[i]放入桶中
            if (bucket_num - 1) in all_buckets and abs(all_buckets[bucket_num - 1] - nums[i]) <= t: # 检查前一个桶
                return True
            if (bucket_num + 1) in all_buckets and abs(all_buckets[bucket_num + 1] - nums[i]) <= t: # 检查后一个桶
                return True
            # 如果不构成返回条件,那么当i >= k 的时候就要删除旧桶了,以维持桶中的元素索引跟下一个i+1索引只差不超过k
            if i >= k:
                all_buckets.pop(nums[i-k]//bucket_size)
        return False

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值