LC
P11 . Longest Palindromic Subsequence
哇,好久没做这种dp的palindrom了。感觉好有意思,被虐得不行,不过我总觉得大佬们的O(n) space的solution大多数时候都是先用O(n^2)然后再优化出来的吧。
这道题主要是把递归公式推到出来就好做了。那个*2是为了让j-1<0的时候不要越界。
如果s[i] == s[j]:
dp[i][j] = 2 + dp[i+1][j-1] if i + 1 <= j - 1 else 2
不然的话
dp[i][j] = max(dp[i][j-1], dp[i+1][j])
class Solution(object):
def longestPalindromeSubseq(self, s):
"""
:type s: str
:rtype: int
"""
if not s: return 0
n = len(s)
dp = [[1]*n*2 for _ in range(n)]
print(dp)
for i in range(0, n-1)[::-1]:
for j in range(i, n):
if s[i] == s[j]:
dp[i][j] = 2 + dp[i+1][j-1] if i + 1 <= j - 1 else 2
else:
dp[i][j] = max(dp[i][j-1], dp[i+1][j])
print dp
return dp[0][n/2]
s = Solution()
ans = s.longestPalindromeSubseq("bbbab")
print ans
P12. Top K Frequent Words
这道题好像可以用python的counter直接取巧。1行都可以解决
import collections
class Solution(object):
def topKFrequent(self, words, k):
"""
:type words: List[str]
:type k: int
:rtype: List[str]
"""
counter = collections.Counter(words)
tmp = counter.most_common(k)
return [val[0] for val in tmp]
s = Solution()
ans = s.topKFrequent(["i", "love", "leetcode", "i", "love", "coding", "i"], 2)
print ans
也可以先用counter然后再用一个heap来维护频率最高的几个单词。
import collections
import heapq
class Solution(object):
def topKFrequent(self, words, k):
"""
:type words: List[str]
:type k: int
:rtype: List[str]
"""
counter = collections.Counter(words)
freqs = []
for word, count in counter.items():
heapq.heappush(freqs, (count, word))
if len(freqs) > k:
heapq.heappop(freqs)
res = []
for _ in range(k):
res.append(heapq.heappop(freqs)[1])
return res[::-1]
s = Solution()
ans = s.topKFrequent(["i", "love", "leetcode", "i", "love", "coding", "i"], 2)
print ans
P13. Combination Sum
我是一直觉得这道题挺好的。非常典型的一道dfs的问题。
class Solution(object):
def combinationSum(self, candidates, target):
"""
:type candidates: List[int]
:type target: int
:rtype: List[List[int]]
"""
return self.helper(candidates, target, [])
def helper(self, nums, target, path, index=0, res=[]):
# base case
if target < 0:
return
if target == 0:
res.append(path)
# recursion body
for i in range(index, len(nums)):
self.helper(nums, target - nums[i], path + [nums[i]], i)
return res
s = Solution()
ans = s.combinationSum([2, 3, 6, 7], 7)
print ans
P14. Insert Delete GetRandom O(1)
本来以为一个set就够了。结果发现python里面set不支持index。所以需要用一个array来存数,然后一个hash table来存数的位置。
import random
class RandomizedSet(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.nums = []
self.pos = {}
def insert(self, val):
"""
Inserts a value to the set. Returns true if the set did not already contain the specified element.
:type val: int
:rtype: bool
"""
if val not in self.pos:
self.nums.append(val)
self.pos[val] = len(self.nums) - 1
return True
return False
def remove(self, val):
"""
Removes a value from the set. Returns true if the set contained the specified element.
:type val: int
:rtype: bool
"""
if val in self.pos:
ind = self.pos[val]
self.nums[ind] = self.nums[-1]
self.pos[self.nums[-1]] = ind
self.nums.pop()
self.pos.pop(val, 0)
return True
return False
def getRandom(self):
"""
Get a random element from the set.
:rtype: int
"""
return random.choice(self.nums) if self.nums else None
val = 0
obj = RandomizedSet()
param_1 = obj.insert(val)
param_2 = obj.remove(val)
param_3 = obj.getRandom()
P15. Swap Nodes in Pairs
我觉得这道题,其实命名特别重要,不然写出来也是一团糟别人看不懂。
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head and not haed.next:
return head
dummy = ListNode('#')
pre_head = dummy
while head and head.next:
# store nodes
first = head
second = head.next
new_head = second.next
# shift order
second.next = first
first.next = new_head
pre_head.next = second
# update nodes
pre_head = first
head = pre_head.next
return dummy.next
a = ListNode(1)
b = ListNode(2)
c = ListNode(3)
d = ListNode(4)
e = ListNode(5)
a.next, b.next, c.next, d.next = b, c, d, e
print a.val, a.next.val, a.next.next.val, a.next.next.next.val
s = Solution()
ans = s.swapPairs(a)
print ans.val, ans.next.val, ans.next.next.val, ans.next.next.next.val, ans.next.next.next.next.val
P16. Delete Node in a BST
这道题的递推解法的思路是,如果找到了那个node. 那么把那个node的右subtree给加到node左边subtree的right most node的right.然后再返回node的left child。
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
def deleteNode(self, root, key):
"""
:type root: TreeNode
:type key: int
:rtype: TreeNode
"""
if not root:
return None
if root.val == key:
if root.left:
left_right_most = root.left
while left_right_most.right:
left_right_most = left_right_most.right
left_right_most.right = root.right
return root.left
else:
return root.right
elif root.val > key:
root.left = self.deleteNode(root.left, key)
else:
root.right = self.deleteNode(root.right, key)
return root
a = TreeNode(1)
b = TreeNode(2)
c = TreeNode(3)
b.left, b.right = a, c
so = Solution()
root = so.deleteNode(b, 1)
print root.val, root.right.val
突然想起bb当年挂我的一道题。找second largest node in BST。
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
def secondLargest(self, root):
"""
:type root: TreeNode
:type key: int
:rtype: TreeNode
"""
pre = None
while root.right:
pre = root
root = root.right
if not root.left:
return pre
cur = root.left
while cur.right:
cur = cur.right
return cur
a = TreeNode(1)
b = TreeNode(2)
c = TreeNode(3)
d = TreeNode(2.5)
b.left, b.right = a, c
c.left = d
so = Solution()
ans = so.secondLargest(b)
print ans.val
P17. Asteroid Collision
用stack来解决。好多corner case。没想到我写的一遍就过了。
class Solution(object):
def asteroidCollision(self, asteroids):
"""
:type asteroids: List[int]
:rtype: List[int]
"""
stack = []
for n in asteroids:
if not stack or n > 0:
stack.append(n)
else:
# if last digit is negative we append
if stack[-1] < 0:
stack.append(n)
else:
# if last digit is positive we need to break as much asteroid as we can
while stack and stack[-1] > 0 and stack[-1] < -n:
stack.pop()
# if is equal, break both
if stack and stack[-1] == -n:
stack.pop()
# if last digit is negative just append.
elif not stack or stack[-1] < 0:
stack.append(n)
return stack
so = Solution()
ans = so.asteroidCollision([5, 10, -5])
print ans
P18. Group Anagrams
hmmm, 被考到这道题的candidate前世一定是拯救了世界。
import collections
class Solution(object):
def groupAnagrams(self, strs):
"""
:type strs: List[str]
:rtype: List[List[str]]
"""
dic = collections.defaultdict(list)
for s in strs:
key = ''.join(sorted(s))
dic[key].append(s)
return dic.values()
so = Solution()
ans = so.groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"])
print ans
P19. Valid Sudoku
好吧,这道题写了那么多次,居然不是一次就过。
class Solution(object):
def isValidSudoku(self, board):
"""
:type board: List[List[str]]
:rtype: bool
"""
if not board or not board[0]:
return True
d = set()
n, m = len(board), len(board[0])
for i in range(n):
for j in range(m):
num = board[i][j]
if num != '.':
if (i, 'row', num) in d:
return False
if ('col', j, num) in d:
return False
if (i//3, j//3, num) in d:
return False
d.add((i, 'row', num))
d.add(('col', j, num))
d.add((i//3, j//3, num))
return True
so = Solution()
ans = so.isValidSudoku(
[
[".",".","4",".",".",".","6","3","."],
[".",".",".",".",".",".",".",".","."],
["5",".",".",".",".",".",".","9","."],
[".",".",".","5","6",".",".",".","."],
["4",".","3",".",".",".",".",".","1"],
[".",".",".","7",".",".",".",".","."],
[".",".",".","5",".",".",".",".","."],
[".",".",".",".",".",".",".",".","."],
[".",".",".",".",".",".",".",".","."]])
print ans
P20. Letter Combinations of a Phone Number
class Solution(object):
def letterCombinations(self, digits):
"""
:type digits: str
:rtype: List[str]
"""
dic = {'2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl',
'6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'}
return self.dfs(digits, [''], dic)
def dfs(self, digits, res, dic):
if not digits:
return res
chars = dic.get(digits[0])
tmp = []
for c in chars:
for letter in res:
tmp.append(letter + c)
return self.dfs(digits[1:], tmp, dic)
s = Solution()
ans = s.letterCombinations('23')
print ans
来一个大神的解法。
class Solution(object):
def letterCombinations(self, digits):
"""
:type digits: str
:rtype: List[str]
"""
if '' == digits: return []
kvmaps = {
'2': 'abc',
'3': 'def',
'4': 'ghi',
'5': 'jkl',
'6': 'mno',
'7': 'pqrs',
'8': 'tuv',
'9': 'wxyz'
}
res=['']
for c in digits:
tmp=[]
for x in res:
for y in kvmaps[c]:
tmp.append(x+y)
res=tmp
return res
s = Solution()
ans = s.letterCombinations('23')
print ans