Tag Hard

Airbnb tag题真的好少啊。等做完hard我就去刷面经。

P1. Merge k Sorted Lists

真是经典老题啊。用heap来implement一个priority queue. 写得时候 第一遍还是有一些edge case和拼写错误,真的是太久没刷了!

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None
import heapq
class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        heap = []
        dummy = ListNode()
        cur = dummy

        for node in lists:
            if node:
                heapq.heappush(heap, [node.val, node])

        while heap:
            tmp = heapq.heappop(heap)
            cur.next = tmp
            cur = cur.next
            if tmp.next:
                heapq.heappush(heap, tmp.next)

        return dummy.next

P2. Palindrome Pairs

先写一个最暴力的naive approach吧。

class Solution:
    def palindromePairs(self, words):
        """
        :type words: List[str]
        :rtype: List[List[int]]
        """
        n = len(words)
        res = []

        for i in range(n-1):
            for j in range(i+1, n):
                tmp = words[i] + words[j]
                if tmp == tmp[::-1]:
                    res.append([i, j])
                tmp = words[j] + words[i]
                if tmp == tmp[::-1]:
                    res.append([j, i])

        return res


args = [["abcd", "dcba", "lls", "s", "sssll"]]
s = Solution()
ans = s.palindromePairs(*args)
print(ans)

其实general idea还是挺简单的,就是各种corner case,太恶心了。先放这里吧,到时候回头来再写一遍

class Solution:
    def palindromePairs(self, words):
        """
        :type words: List[str]
        :rtype: List[List[int]]
        """
        d = dict([(w, i) for i, w in enumerate(words)])
        res = []
        for i, w in enumerate(words):
            for j in xrange(len(w)+1):
                prefix, postfix = w[:j], w[j:]
                if prefix[::-1] in d and i != d[prefix[::-1]] and postfix == postfix[::-1]:
                    res.append([i, d[prefix[::-1]]])
                if j>0 and postfix[::-1] in d and i != d[postfix[::-1]] and prefix == prefix[::-1]:
                    res.append([d[postfix[::-1]], i])
        return res 


args = [["abcd", "dcba", "lls", "s", "sssll"]]
s = Solution()
ans = s.palindromePairs(*args)
print(ans)

P3.Alien Dictionary

经典中的 经典啊!朕还能挣扎着写出来,说明宝刀未老!

import collections
class Solution(object):
    def alienOrder(self, words):
        """
        :type words: List[str]
        :rtype: str
        """
        pre = collections.defaultdict(set)
        suc = collections.defaultdict(set)

        for i in range(len(words)-1):
            top = words[i]
            bot = words[i+1]
            for i in range(min(len(top), len(bot))):
                if top[i] != bot[i]:
                    pre[top[i]].add(bot[i])
                    suc[bot[i]].add(top[i])
                    break

        chars = set(''.join(words))
        root = chars - set(suc.keys())
        res = ''
        while root:
            tmp = root.pop()
            res += tmp
            for c in pre[tmp]:
                suc[c].remove(tmp)
                if not suc[c]:
                    root.add(c)

        return res if len(res) == len(chars) else ''


args = [[
  "wrt",
  "wrf",
  "er",
  "ett",
  "rftt"
]]
s = Solution()
ans = s.alienOrder(*args)
print(ans)

P4. Regular Expression Matching

这道题跟 Wildcard Matching 是兄弟题型。感觉airbnb还是有点会选题目的,都是我以前做过的,觉得比较经典的题目。

确实有点不太好写,有一些比较tricky的corner case.

class Solution(object):
    def isMatch(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: bool
        """

        dp = [ [False]*(len(s) + 1) for _ in range(len(p) + 1) ]
        dp[0][0] = True

        for i in range(1, len(p) + 1):
            for j in range(1, len(s) + 1):
                if p[i-1] == '.':
                    dp[i][j] = dp[i-1][j-1]
                elif p[i-1] == '*':
                    dp[i][j] = dp[i-1][j-1] or dp[i-1][j] or dp[i][j-1]
                    if i >= 2 and j >= 2:
                        dp[i][j-2] = dp[i-2][j-2]
                else:
                    dp[i][j] = dp[i-1][j-1] and p[i-1] == s[j-1]

        return dp[-1][-1] == 1

args = ["aab", "c*a*b"]
s = Solution()
print s.isMatch("aa","a")
print s.isMatch("aa","aa")
print s.isMatch("aaa","aa")
print s.isMatch("aa", "a*")
print s.isMatch("aa", ".*")
print s.isMatch("ab", ".*")
print s.isMatch("aab", "c*a*b")

P5. Word Search II

不得不说,这也是一道非常好的题目。不过我真的觉得 如果onsite的时候考candidate这道题,除非是45分钟全部用来做题。不然90%都会跪吧。详细的思路在这里

我一天面点别人combination sum,这些小朋友都写得磕磕绊绊的。挣扎着写完了这道题。我的奶奶呀。

class Node(object):
    def __init__(self):
        self.children = {}
        self.isWord = False

class Solution(object):

    def findWords(self, board, words):
        """
        :type board: List[List[str]]
        :type words: List[str]
        :rtype: List[str]
        """
        if not board or not board[0]:
            return []

        # build a Trie
        root = Node()
        for w in words:
            tmp = root
            for c in w:
                if c not in tmp.children:
                    tmp.children[c] = Node()
                tmp = tmp.children[c]
            tmp.isWord = True

        n, m = len(board), len(board[0])
        res = []
        for i in range(n):
            for j in range(m):
                c = board[i][j]
                if c in root.children:
                    node = root.children[c]
                    visited = [[False]*m for _ in range(n)]
                    self.find(board, node, i, j, c, res, visited)

        return res


    def find(self, board, node, d, p, path, res, visited):
        visited[d][p] = True

        if node.isWord:
            res.append(path)
            node.isWord = False

        for i, j in [(d-1, p), (d+1, p), (d, p-1), (d, p+1)]:
            if 0 <= i < len(board) and 0 <= j < len(board[0]) and not visited[i][j]:
                if board[i][j] in node.children:
                    newNode = node.children[board[i][j]]
                    self.find(board, newNode, i, j, path+board[i][j], res, visited)

args = [ [
  ['o','a','a','n'],
  ['e','t','a','e'],
  ['i','h','k','r'],
  ['i','f','l','v']
], ["oath","pea","eat","rain"]]
s = Solution()
ans = s.findWords(*args)
print(ans)

P6. Text Justification

这道题到时不难,就是些起来有点恶心。不过话说回来了,什么题不恶心。2sum最不恶心。哈哈

class Solution(object):
    def fullJustify(self, words, maxWidth):
        """
        :type words: List[str]
        :type maxWidth: int
        :rtype: List[str]
        """

        stack = []
        curLen = 0
        res = []
        for w in words:
            if not stack:
                newLen = len(w)
            else:
                newLen = len(w)  + 1

            if curLen + newLen > maxWidth:
                # generate a new line
                newLine = ' '.join(stack)
                res.append(newLine)
                # clear stack
                stack = [w]
                curLen = len(w)
            else:
                stack.append(w)
                curLen += newLen

        if stack:
            newLine = ' '.join(stack)
            res.append(newLine)

        return res


words = ["This", "is", "an", "example", "of", "text", "justification."]
maxWidth = 16
args = [words, maxWidth]
s = Solution()
ans = s.fullJustify(*args)
print(ans)

好吧 这个哥哥写得比我好多了。那个round robin确实写得好,不过我感觉他那个复杂度好高啊。每次 ' ' + ' '加的时候都会copy整个字符串。

class Solution(object):
    def fullJustify(self, words, maxWidth):
        """
        :type words: List[str]
        :type maxWidth: int
        :rtype: List[str]
        """
        res, cur, num_of_letters = [], [], 0
        for w in words:
            if num_of_letters + len(w) + len(cur) > maxWidth:
                for i in range(maxWidth - num_of_letters):
                    cur[i%(len(cur)-1 or 1)] += ' '
                res.append(''.join(cur))
                cur, num_of_letters = [], 0
            cur += [w]
            num_of_letters += len(w)
        return res + [' '.join(cur).ljust(maxWidth)]

words = ["This", "is", "an", "example", "of", "text", "justification."]
maxWidth = 16
args = [words, maxWidth]
s = Solution()
ans = s.fullJustify(*args)
print(ans)

results matching ""

    No results matching ""