sc 11-20
P11: Trapping rain water。
https://leetcode.com/problems/trapping-rain-water/
思路:左右两个pointer 然后每次动矮的那一个。然后分别记录左右最高的
class Solution(object):
def trap(self, height):
"""
:type height: List[int]
:rtype: int
"""
if not height or len(height)<3:
return 0
l ,r = 0, len(height)-1
left_h, right_h = height[l], height[r]
res = 0
while l<r:
if left_h<right_h:
res += max(0, left_h-height[l+1])
l = l+1
left_h = max(left_h, height[l])
else:
res += max(0, right_h-height[r-1])
r = r-1
right_h = max(right_h, height[r])
return res
P12: 给定字符串A,B, 判断A中是否存在子串是B的anagram 。
https://leetcode.com/problems/valid-anagram/
leet有道简单版的。再上一道难的。
class Solution(object):
def isAnagram(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
return collections.Counter(s) == collections.Counter(t)
难的版本
class Solution(object):
def isAnagram(self, a, b):
"""
:type a: str
:type b: str
:rtype: bool
"""
if len(b)> len(a):
return False
b = sorted(b)
for i in range(len(a)-len(b)+1):
if sorted(a[i:i+len(b)]) == b:
return True
return False
s = "sadaanagramsad"
t = "nagaram"
so = Solution()
print so.isAnagram(s,t)
更优化的版本用sliding window + hash来做。
import collections
class Solution(object):
def isAnagram(self, a, b):
"""
:type a: str
:type b: str
:rtype: bool
"""
da = collections.defaultdict(int)
db = collections.defaultdict(int)
if len(b)> len(a):
return False
for c in b:
db[c] += 1
for i in range(len(b)):
da[a[i]] += 1
if da == db:
return True
for i in range(1, len(a) - len(b) + 1):
da[a[i-1]] -= 1
da[a[i+len(b)-1]] += 1
if self.compare(db, da):
return True
return False
def compare(self, d1, d2):
for k in d1:
if k not in d2 or d1[k]!=d2[k]:
return False
return True
s = "sadaanagramsad"
s = "aasdadnagaram"
t = "nagaram"
so = Solution()
print so.isAnagram(s,t)
P13. 第一轮是一个妹子, 好像是某硬件组的, 具体不记得了, 就记得妹子长得还不错lol 我记得开始就问了下我背景和做过什麽, 看起来很有兴趣的样子。然后做题, 先是建一个event, 里面有start time和end time, 然后check这两个event有没有conflict, 各种if else, 然后升级, 给一个list of events, 直接sort他们。再升级, 建一个schedule, 给几个office, 问怎么样的solution才是optimal的。
leetcode meeting room I//meeting room II
https://leetcode.com/problems/meeting-rooms/
https://leetcode.com/problems/meeting-rooms-ii/
思路: 写了下难的那道。扫描线算法。然后存avaliable和房间数。
class Solution(object):
def minMeetingRooms(self, intervals):
"""
:type intervals: List[List[int]]
:rtype: int
"""
# put all the times together and sort them.
times = []
for i in intervals:
times.append((i[0], 1))
times.append((i[1], 0))
times.sort()
count = 0
availiable = 0
for t in times:
# if we need a room
# avaliabe room -1.
if t[1]:
availiable -= 1
if availiable<0:
availiable += 1
count += 1
# if end a meeting
# avaliable + 1
else:
availiable += 1
return count
intervals = [[0, 30],[5, 10],[15, 20]]
so = Solution()
print so.minMeetingRooms(intervals)
P14. 首先, 一个array的range是1-N,这个array里有1+N个数, 找出这个array里的duplicate。(ex. [1, 1, 3, 5]) HashMap 解决然后条件升级, 问不能用extra space. 想了一下, 先sort, 再找再升级, 不能改变array, 不能有extra space。
287 Find the Duplicate Number
https://leetcode.com/problems/find-the-duplicate-number/
最后跟linked list 找circle一样的。
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
slow = nums[0]
fast = nums[nums[0]]
while (slow != fast):
slow = nums[slow]
fast = nums[nums[fast]]
fast = 0;
while (fast != slow):
fast = nums[fast]
slow = nums[slow]
return slow
P15. binary tree to doubly linked list.
https://leetcode.com/problems/flatten-binary-tree-to-linked-list/
思路:这道题是数flatten成单项链表,面试题目相当于是加强版。就是preorder里面加点料。需要注意的地方是我们这个 self.pre = root这里很精妙,相当于在flatten右边树之前,把左树的最后一个节点给存起来了。
class Solution(object):
pre = None
def flatten(self, root):
"""
:type root: TreeNode
:rtype: void
"""
if root:
self.pre = root
self.flatten(root.left)
tmp = root.right
root.right = root.left
root.left = None
self.pre.next = root.right
self.flatten(tmp)
加强版:因为我们需要双向链表。所以要记录这个node的parent.因为Input变成了2个,所以我们需要新写一个helper function呢。
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
pre = None
def flatten(self, root):
"""
:type root: TreeNode
:rtype: void
"""
self.helper(root, None)
def helper(self, root, p):
if root:
self.pre = root
self.helper(root.left, root)
tmp = root.right
root.right = root.left
root.left = p
self.pre.next = root.right
self.helper(tmp, self.pre)
a = TreeNode(1)
b = TreeNode(2)
c = TreeNode(3)
a.left, a.right = b, c
so = Solution()
so.flatten(a)
print a.val, a.right.val, a.right.left.val
P16. search in rotated array 。
https://leetcode.com/problems/search-in-rotated-sorted-array/
https://leetcode.com/problems/search-in-rotated-sorted-array-ii/
思路:这道题跟一般的之前那个rotated sorted array找最小的值不一样,这个是要search。先找出带顺序的那一半,然后再判断在不在里面。 (睡了一觉刚醒,起来做这个就是思路清晰,corner case毫无破绽!
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if not nums:
return -1
l, r = 0, len(nums)-1
while l<r:
mid = (l+r)//2
if nums[mid] == target:
return mid
if nums[mid]<nums[r]:
if nums[mid]<target<=nums[r]:
l = mid+1
else:
r = mid
else:
if nums[l]<=target<nums[mid]:
r = mid
else:
l = mid+1
return l if nums[l]==target else -1
nums = [4, 5, 6, 7, 0, 1, 2]
so = Solution()
print so.search(nums, 0)
再写个加强版,带重复的,其实就是多了一个如果mid == r 然后r--而已。 跟P5的思想一样。
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: bool
"""
if not nums:
return -1
l, r = 0, len(nums)-1
while l<r:
mid = (l+r)//2
if nums[mid] == target:
return True
if nums[mid]<nums[r]:
if nums[mid]<target<=nums[r]:
l = mid+1
else:
r = mid
elif nums[mid]==nums[r]:
r -= 1
else:
if nums[l]<=target<nums[mid]:
r = mid
else:
l = mid+1
return True if nums[l]==target else False
P17.上来面试官先介绍了一下他做的工作,人很nice,中国帅哥,然后让我介绍了我的projects 和 背景。之后出了一道题目: // Give a stream of numbers // Write a method to return the medium of the numbers you have received // void add(int num); // int getMedium();
https://leetcode.com/problems/find-median-from-data-stream/
import heapq
class MedianFinder:
def __init__(self):
"""
Initialize your data structure here.
"""
self.min_heap = []
self.max_heap = []
def addNum(self, num):
"""
Adds a num into the data structure.
:type num: int
:rtype: void
"""
if len(self.min_heap)==len(self.max_heap):
heapq.heappush(self.min_heap, num)
heapq.heappush(self.max_heap, -heapq.heappop(self.min_heap))
else:
heapq.heappush(self.max_heap, -num)
heapq.heappush(self.min_heap, -heapq.heappop(self.max_heap))
def findMedian(self):
"""
Returns the median of current data stream
:rtype: float
"""
if len(self.min_heap)==len(self.max_heap):
return (self.min_heap[0] - self.max_heap[0])/2.0
else:
return -self.max_heap[0]
P18. 我一开始就想当然的用了个二维int矩阵做参数。 然后他memory overhead是什么,我就说我mn4。 问能不能省,我就说其实不需要用int存状态,用两个bit就可以了。 又问如果还要再省一点呢?我就说,如果要操作的点不太多的话,那就不要存矩阵了,就存存要修改的点的坐标。 然后又问怎么做,我才意识到他是想说参数其实不必用矩阵,就用一个list of coordinates,然后就说如果是sparse矩阵的话就只扫一下live的点,然后看看它和它neighbor在下一轮是什么状态就好了。 但是这个时候时间已经差不多了,就没有再写实现。
https://leetcode.com/problems/game-of-life/
前天才写了一遍,今天就不写了。
class Solution(object):
def gameOfLife(self, board):
"""
:type board: List[List[int]]
:rtype: void Do not return anything, modify board in-place instead.
"""
if not board or not board[0]:
return
for i in range(len(board)):
for j in range(len(board[0])):
cnt = 0
for m, n in [[i-1, j],[i+1, j], [i, j-1], [i, j+1], [i-1, j-1], [i+1, j+1], [i+1, j-1], [i-1, j+1]]:
if 0<=m<len(board) and 0<=n<len(board[0]):
if board[m][n]&1 ==1:
cnt += 1
if board[i][j]==1:
if 3<=board[i][j]+cnt<=4:
board[i][j] = board[i][j]^2
else:
if cnt==3:
board[i][j] = board[i][j]^2
print cnt
for i in range(len(board)):
for j in range(len(board[0])):
board[i][j] = board[i][j]>>1
P19. 1. permutation i。leetcode原题,没有任何改变。
https://leetcode.com/problems/permutations-ii/
Permutation I 太简单,我们还是写permutaiont II好了
class Solution(object):
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res=[]
self.size=len(nums)
nums.sort()
self.dfs(nums,[],res)
return res
def dfs(self,nums,cur,res):
if len(cur)==self.size:
res.append(cur)
return
for i in range(len(nums)):
if i and nums[i]==nums[i-1]:
continue
self.dfs(nums[:i]+nums[i+1:], cur+[nums[i]], res)
nums = [1,2,3]
so = Solution()
print so.permuteUnique(nums)
P20. 24点游戏。给你几个数字,判断他们做加减乘除运算是否可以得到24,顺序可以是任意的。dfs搜索搞定。。。但是这里要注意一些细节,每次计算得到新的数之后最好加入数组做下一次搜索,不然容易出错。
class Solution(object):
def game24(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
return self.dfs(nums, 0, '')
def dfs(self, nums, cur, path):
"""
:type nums: List[int]
:type cur: int
:type path: str
:rtype: bool
"""
if not nums and cur==24:
print path
return True
for i in range(len(nums)):
if self.dfs(nums[:i]+nums[i+1:], cur+nums[i], path+'+'+str(nums[i])):
return True
if self.dfs(nums[:i]+nums[i+1:], cur-nums[i], path+'-'+str(nums[i])):
return True
if self.dfs(nums[:i]+nums[i+1:], cur*nums[i], path+'*'+str(nums[i])):
return True
if self.dfs(nums[:i]+nums[i+1:], cur/nums[i], path+'/'+str(nums[i])):
return True
return False
nums = [4,2,1,3]
so = Solution()
print so.game24(nums)