题目序号

Strobogrammatic Number I, II, III

A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down).

Write a function to determine if a number is strobogrammatic. The number is represented as a string.

For example, the numbers “69”, “88”, and “818” are all strobogrammatic.

class Solution:
# @param {string} low
# @param {string} high
# @return {integer}
def strobogrammaticInRange(self, low, high):
    a=self.below(high)
    b=self.below(low,include=False)
    return a-b if a>b else 0

'''
get how many strobogrammatic numbers less than n
'''
def below(self,n,include=True):
    res=0
    for i in range(1,len(n)):
        res+=self.number(i)
    l=self.strobogrammatic(len(n))
    '''
    filter num larger than n and start with 0
    '''
    if include:
        l=[num for num in l if (len(num)==1 or num[0]!='0') and num<=n]
    else:
        l=[num for num in l if (len(num)==1 or num[0]!='0') and num<n]
    return res+len(l)

'''
get strobogrammatic numbers with length l
number start with 0 would be included
'''
def strobogrammatic(self,l):
    res=[]
    if l==1:
        return ['0','1','8']
    if l==2:
        return ['00','11','69','96','88']
    for s in self.strobogrammatic(l-2):
        res.append('0'+s+'0')
        res.append('1'+s+'1')
        res.append('6'+s+'9')
        res.append('8'+s+'8')
        res.append('9'+s+'6')
    return res

'''
get number of strobogrammatic numbers of length l
'''
def number(self,l):
    if l==0:
        return 0
    '''
    If l is an even number, the first digit has four choices (1,6,8,9). digits
    at other position have five choices(0,1,6,8,9)
    '''
    if l%2==0:
        return 4*(5**(l/2-1))
    '''
    If l is an odd number, the first digit has four choices (1,6,8,9) and digit
    at the middle has 3 choices (0,1,8),other digits have 5 choices.
    digit at other position could be 0,1,6,8,9
    '''
    elif l==1:
        return 3
    else:
        return 3*(5**(l/2-1))*4


def strobogrammaticInRange(self, low, high):
    a, b = self.below(high), self.below(low, include=False)
    return a -b if a > b else 0

def below(self, n, include=True):
    res = 0
    for i in xrange(1, len(n)):
        res += self.number(i)
    l = self.strobogrammatic(len(n))
    if include:
        tmp = [num for num in l if num <= n]
    else:
        tmp = [num for num in l if num < n]
    return res + len(tmp)

def strobogrammatic(self, n):
    return self.helper(n, n)

def helper(self, m, n):
    if m == 0:
        return [""]
    if m == 1:
        return ["0", "1", "8"]
    l = self.helper(m-2, n)
    res = []
    for i in l:
        if m != n:
            res.append("0"+i+"0")
        res.append("1"+i+"1")
        res.append("6"+i+"9")
        res.append("8"+i+"8")
        res.append("9"+i+"6")
    return res

60. Permutation Sequence

The set [1,2,3,…,n] contains a total of n! unique permutations.

By listing and labeling all of the permutations in order, we get the following sequence for n = 3:

"123"
"132"
"213"
"231"
"312"
"321"
Given n and k, return the kth permutation sequence.

Note:

Given n will be between 1 and 9 inclusive. Given k will be between 1 and n! inclusive. Example 1:

Input: n = 3, k = 3 Output: “213” Example 2:

Input: n = 4, k = 9 Output: “2314”

# TLE
def getPermutation(self, n, k):
    nums = range(1, n+1)
    for i in xrange(k-1):
        self.nextPermutation(nums)
    return "".join(map(str, nums))

def nextPermutation(self, nums):
    l = d = m = len(nums)-1
    while l > 0 and nums[l] <= nums[l-1]:
        l -= 1
    if l == 0:
        nums.reverse()
        return
    k = l-1
    while nums[k] >= nums[d]:
        d -= 1
    nums[k], nums[d] = nums[d], nums[k]
    while l < m:
        nums[l], nums[m] = nums[m], nums[l]
        l += 1; m -= 1

# AC
def getPermutation(self, n, k):
    res, nums = "",  range(1, n+1)
    k -= 1
    while n:
        n -= 1
        index, k = divmod(k, math.factorial(n))
        res += str(nums.pop(index))
    return res

145. Binary Tree Postorder Traversal 二叉树的后序遍历

Given a binary tree, return the postorder traversal of its nodes’ values.

Example:

Input: [1,null,2,3]
   1
    \
     2
    /
   3

Output: [3,2,1]

Follow up: Recursive solution is trivial, could you do it iteratively?

给定一个二叉树,返回它的 后序 遍历。

示例:

输入: [1,null,2,3]
1
2

/

3

输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成吗?

# recursively
def postorderTraversal1(self, root):
    res = []
    self.dfs(root, res)
    return res

def dfs(self, root, res):
    if root:
        self.dfs(root.left, res)
        self.dfs(root.right, res)
        res.append(root.val)

# iteratively
def postorderTraversal(self, root):
    res, stack = [], [root]
    while stack:
        node = stack.pop()
        if node:
            res.append(node.val)
            stack.append(node.left)
            stack.append(node.right)
    return res[::-1]


def postorderTraversal(self, root):
    res = []
    self.dfs(root, res)
    return res[::-1]

def dfs(self, root, res):
    if root:
        res.append(root.val)
        self.dfs(root.right, res)
        self.dfs(root.left, res)



The first is by postorder using a flag to indicate whether the node has been visited or not.

class Solution:
    # @param {TreeNode} root
    # @return {integer[]}
    def postorderTraversal(self, root):
        traversal, stack = [], [(root, False)]
        while stack:
            node, visited = stack.pop()
            if node:
                if visited:
                    # add to result if visited
                    traversal.append(node.val)
                else:
                    # post-order
                    stack.append((node, True))
                    stack.append((node.right, False))
                    stack.append((node.left, False))

        return traversal
The 2nd uses modified preorder (right subtree first). Then reverse the result.

class Solution:
    # @param {TreeNode} root
    # @return {integer[]}
    def postorderTraversal(self, root):
        traversal, stack = [], [root]
        while stack:
            node = stack.pop()
            if node:
                # pre-order, right first
                traversal.append(node.val)
                stack.append(node.left)
                stack.append(node.right)

        # reverse result
        return traversal[::-1]

241. Different Ways to Add Parentheses

Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +, - and *.

Example 1:

Input: "2-1-1"
Output: [0, 2]
Explanation:
((2-1)-1) = 0
(2-(1-1)) = 2

Example 2:

Input: "2*3-4*5"
Output: [-34, -14, -10, -10, 10]
Explanation:
(2*(3-(4*5))) = -34
((2*3)-(4*5)) = -14
((2*(3-4))*5) = -10
(2*((3-4)*5)) = -10
(((2*3)-4)*5) = 10
def diffWaysToCompute(self, input):
    if input.isdigit():
        return [int(input)]
    res = []
    for i in xrange(len(input)):
        if input[i] in "-+*":
            res1 = self.diffWaysToCompute(input[:i])
            res2 = self.diffWaysToCompute(input[i+1:])
            for j in res1:
                for k in res2:
                    res.append(self.helper(j, k, input[i]))
    return res

def helper(self, m, n, op):
    if op == "+":
        return m+n
    elif op == "-":
        return m-n
    else:
        return m*n



 def diffWaysToCompute(self, input):
    if input.isdigit():
        return [eval(input)]
    res = []
    for i, s in enumerate(input):
        if s in "+-*":
            l = self.diffWaysToCompute(input[:i])
            r = self.diffWaysToCompute(input[i+1:])
            res.extend(self.compute(l, r, s))
    return res

def compute(self, l, r, op):
    return [eval(str(m)+op+str(n)) for m in l for n in r]



def diffWaysToCompute(self, input):
    if input.isdigit():
        return [int(input)]
    res = []
    for i in xrange(len(input)):
        if input[i] in "-+*":
            res1 = self.diffWaysToCompute(input[:i])
            res2 = self.diffWaysToCompute(input[i+1:])
            res += [eval(str(k)+input[i]+str(j)) for k in res1 for j in res2]
    return res



def diffWaysToCompute(self, input):
    if input.isdigit():
        return [int(input)]
    res = []
    for i in xrange(len(input)):
        if input[i] in "-+*":
            res1 = self.diffWaysToCompute(input[:i])
            res2 = self.diffWaysToCompute(input[i+1:])
            for j in res1:
                for k in res2:
                    res.append(self.helper(j, k, input[i]))
    return res

def helper(self, m, n, op):
    if op == "+":
        return m+n
    elif op == "-":
        return m-n
    else:
        return m*n
def diffWaysToCompute(self, input):
    if input.isdigit():
        return [int(input)]
    res = []
    for i in xrange(len(input)):
        if input[i] in "-+*":
            res1 = self.diffWaysToCompute(input[:i])
            res2 = self.diffWaysToCompute(input[i+1:])
            for j in res1:
                for k in res2:
                    res.append(self.helper(j, k, input[i]))
    return res

def helper(self, m, n, op):
    if op == "+":
        return m+n
    elif op == "-":
        return m-n
    else:
        return m*n


An even shorter version:

 def diffWaysToCompute(self, input):
    if input.isdigit():
        return [eval(input)]
    res = []
    for i, s in enumerate(input):
        if s in "+-*":
            l = self.diffWaysToCompute(input[:i])
            r = self.diffWaysToCompute(input[i+1:])
            res.extend(self.compute(l, r, s))
    return res

def compute(self, l, r, op):
    return [eval(str(m)+op+str(n)) for m in l for n in r]


def diffWaysToCompute(self, input):
    if input.isdigit():
        return [int(input)]
    res = []
    for i in xrange(len(input)):
        if input[i] in "-+*":
            res1 = self.diffWaysToCompute(input[:i])
            res2 = self.diffWaysToCompute(input[i+1:])
            res += [eval(str(k)+input[i]+str(j)) for k in res1 for j in res2]
    return res

130. Surrounded Regions

Given a 2D board containing ‘X’ and ‘O’ (the letter O), capture all regions surrounded by ‘X’.

A region is captured by flipping all ‘O’s into ‘X’s in that surrounded region.

Example:

X X X X
X O O X
X X O X
X O X X
After running your function, the board should be:

X X X X
X X X X
X X X X
X O X X

Explanation:

Surrounded regions shouldn’t be on the border, which means that any ‘O’ on the border of the board are not flipped to ‘X’. Any ‘O’ that is not on the border and it is not connected to an ‘O’ on the border will be flipped to ‘X’. Two cells are connected if they are adjacent cells connected horizontally or vertically.

# BFS
def solve(self, board):
    queue = collections.deque([])
    for r in xrange(len(board)):
        for c in xrange(len(board[0])):
            if (r in [0, len(board)-1] or c in [0, len(board[0])-1]) and board[r][c] == "O":
                queue.append((r, c))
    while queue:
        r, c = queue.popleft()
        if 0<=r<len(board) and 0<=c<len(board[0]) and board[r][c] == "O":
            board[r][c] = "D"
            queue.append((r-1, c)); queue.append((r+1, c))
            queue.append((r, c-1)); queue.append((r, c+1))

    for r in xrange(len(board)):
        for c in xrange(len(board[0])):
            if board[r][c] == "O":
                board[r][c] = "X"
            elif board[r][c] == "D":
                board[r][c] = "O"



# BFS
def solve(self, board):
    if not board:
        return
    r, c = len(board), len(board[0])
    for i in xrange(r):
        self.bfs(board, i, 0); self.bfs(board, i, c-1)
    for j in xrange(1, c-1):
        self.bfs(board, 0, j); self.bfs(board, r-1, j)
    # recover the board at second time
    for i in xrange(r):
        for j in xrange(c):
            if board[i][j] == "D":
                board[i][j] = "O"
            else:
                board[i][j] = "X"

def bfs(self, board, i, j):
    queue = collections.deque()
    if board[i][j] == "O":
        queue.append((i, j)); board[i][j] = "D"
    while queue:
        r, c = queue.popleft()
        if r > 0 and board[r-1][c] == "O": # up
            queue.append((r-1, c)); board[r-1][c] = "D"
        if r < len(board)-1 and board[r+1][c] == "O": # down
            queue.append((r+1, c)); board[r+1][c] = "D"
        if c > 0 and board[r][c-1] == "O": # left
            queue.append((r, c-1)); board[r][c-1] = "D"
        if c < len(board[0])-1 and board[r][c+1] == "O": # right
            queue.append((r, c+1)); board[r][c+1] = "D"


Here is a version which bfs function is embedded inside solve function:

# BFS
def solve(self, board):
    if not board:
        return
    row, col = len(board), len(board[0])
    queue = collections.deque()
    for i in xrange(row):
        if board[i][0] == "O":
            queue.append((i, 0))
        if board[i][col-1] == "O":
            queue.append((i, col-1))
    for j in xrange(1, col-1):
        if board[0][j] == "O":
            queue.append((0, j))
        if board[row-1][j] == "O":
            queue.append((row-1, j))
    while queue:
        r, c = queue.popleft()
        board[r][c] = "D"
        if r > 0 and board[r-1][c] == "O": # up
            queue.append((r-1, c))
        if r < row-1 and board[r+1][c] == "O": # down
            queue.append((r+1, c))
        if c > 0 and board[r][c-1] == "O": # left
            queue.append((r, c-1))
        if c < col-1 and board[r][c+1] == "O": # right
            queue.append((r, c+1))
    # recover the board at second time
    for i in xrange(row):
        for j in xrange(col):
            if board[i][j] == "D":
                board[i][j] = "O"
            else:
                board[i][j] = "X"

150. Evaluate Reverse Polish Notation

Evaluate the value of an arithmetic expression in Reverse Polish Notation.

Valid operators are +, -, *, /. Each operand may be an integer or another expression.

Note:

Division between two integers should truncate toward zero. The given RPN expression is always valid. That means the expression would always evaluate to a result and there won’t be any divide by zero operation. Example 1:

Input: [“2”, “1”, “+”, “3”, “*”] Output: 9 Explanation: ((2 + 1) * 3) = 9 Example 2:

Input: [“4”, “13”, “5”, “/”, “+”] Output: 6 Explanation: (4 + (13 / 5)) = 6 Example 3:

Input: [“10”, “6”, “9”, “3”, “+”, “-11”, “*”, “/”, “*”, “17”, “+”, “5”, “+”] Output: 22 Explanation:

((10 * (6 / ((9 + 3) * -11))) + 17) + 5

= ((10 * (6 / (12 * -11))) + 17) + 5 = ((10 * (6 / -132)) + 17) + 5 = ((10 * 0) + 17) + 5 = (0 + 17) + 5 = 17 + 5 = 22

def evalRPN(self, tokens):
    stack = []
    for t in tokens:
        if t not in ["+", "-", "*", "/"]:
            stack.append(int(t))
        else:
            r, l = stack.pop(), stack.pop()
            if t == "+":
                stack.append(l+r)
            elif t == "-":
                stack.append(l-r)
            elif t == "*":
                stack.append(l*r)
            else:
                # here take care of the case like "1/-22",
                # in Python 2.x, it returns -1, while in
                # Leetcode it should return 0
                if l*r < 0 and l % r != 0:
                    stack.append(l/r+1)
                else:
                    stack.append(l/r)
    return stack.pop()


class Solution:
# @param tokens, a list of string
# @return an integer
def evalRPN(self, tokens):
    stack  = []
    for i in tokens:
        try:
            temp = int(i)
            stack.append(temp)
        except Exception, e:
            b,a=stack[-1],stack[-2]
            stack.pop()
            stack.pop()
            if i == '+':    a = a+b
            elif i=='-':    a = a-b
            elif i=='*':    a = a*b
            elif i=='/':    a = int(a*1.0/b)
            stack.append(a)

    return stack[-1]