Phone Interview I
53.reverse-words-in-a-string
1 class Solution: 2 # @param s : A string 3 # @return : A string 4 def reverseWords(self, s): 5 # write your code here 6 return ' '.join(s.strip().split(' ')[::-1])
31.partition-array
给出一个整数数组 nums 和一个整数 k。划分数组(即移动数组 nums 中的元素),使得:
- 所有小于k的元素移到左边
- 所有大于等于k的元素移到右边
返回数组划分的位置,即数组中第一个位置 i,满足 nums[i] 大于等于 k。
1 class Solution: 2 """ 3 @param: : The integer array you should partition 4 @param: : An integer 5 @return: The index after partition 6 """ 7 8 def partitionArray(self, nums, k): 9 # write your code here 10 if not nums: 11 return 0 12 13 left, right = 0, len(nums) - 1 14 while left < right: 15 while left < right and nums[left] < k: 16 left += 1 17 while left < right and nums[right] >= k: 18 right -= 1 19 if left < right and nums[left] >= k and nums[right] < k: 20 nums[left], nums[right] = nums[right], nums[left] 21 22 23 if nums[left] >= k: 24 return left 25 if nums[right] >= k: 26 return right 27 return right + 1
Phone Interview II
167.add-two-numbers
你有两个用链表代表的整数,其中每个节点包含一个数字。数字存储按照在原来整数中相反
的顺序,使得第一个数字位于链表的开头。写出一个函数将两个整数相加,用链表形式返回和。
1 # Definition for singly-linked list. 2 # class ListNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.next = None 6 7 class Solution: 8 # @param l1: the first list 9 # @param l2: the second list 10 # @return: the sum list of l1 and l2 11 def addLists(self, l1, l2): 12 # write your code here 13 rhead = ListNode(0) 14 cur = rhead 15 c = 0 16 while l1 and l2: 17 temp = l1.val + l2.val + c 18 c = temp / 10 19 temp = temp % 10 20 cur.next = ListNode(temp) 21 cur = cur.next 22 l1 = l1.next 23 l2 = l2.next 24 while l1: 25 temp = l1.val + c 26 c = temp / 10 27 temp = temp % 10 28 cur.next = ListNode(temp) 29 cur = cur.next 30 l1 = l1.next 31 while l2: 32 temp = l2.val + c 33 c = temp / 10 34 temp = temp % 10 35 cur.next = ListNode(temp) 36 cur = cur.next 37 l2 = l2.next 38 if c: 39 cur.next = ListNode(c) 40 return rhead.next
88.lowest-common-ancestor
给定一棵二叉树,找到两个节点的最近公共父节点(LCA)。
最近公共祖先是两个节点的公共的祖先节点且具有最大深度。假设给出的两个节点都在树中存在
1 """ 2 Definition of TreeNode: 3 class TreeNode: 4 def __init__(self, val): 5 self.val = val 6 self.left, self.right = None, None 7 """ 8 class Solution: 9 """ 10 @param root: The root of the binary search tree. 11 @param A and B: two nodes in a Binary. 12 @return: Return the least common ancestor(LCA) of the two nodes. 13 """ 14 def lowestCommonAncestor(self, root, A, B): 15 # write your code here 16 result = [] 17 self.findPath(result, [root], root, A) 18 self.findPath(result, [root], root, B) 19 LCA = None 20 i = 0 21 while i < len(result[0]) and i < len(result[1]) and result[0][i] == result[1][i]: 22 LCA = result[0][i] 23 i += 1 24 return LCA 25 26 27 def findPath(self, result, path, root, node): 28 if root == node: 29 result.append(path[:]) 30 return 31 if root.left: 32 path.append(root.left) 33 self.findPath(result, path, root.left, node) 34 path.pop() 35 if root.right: 36 path.append(root.right) 37 self.findPath(result, path, root.right, node) 38 path.pop()
Onsite I
655.big-integer-addition
Given two non-negative integers num1
and num2
represented as string, return the sum of num1
and num2
.
1 class Solution: 2 # @param {string} num1 a non-negative integers 3 # @param {string} num2 a non-negative integers 4 # @return {string} return sum of num1 and num2 5 def addStrings(self, num1, num2): 6 # Write your code here 7 if not num1: 8 return num2 9 if not num2: 10 return num1 11 i, j = len(num1) - 1, len(num2) - 1 12 result = [] 13 c = 0 14 while i >= 0 and j >= 0: 15 tmp = int(num1[i]) + int(num2[j]) + c 16 c = tmp / 10 17 tmp %= 10 18 result.append(str(tmp)) 19 i -= 1 20 j -= 1 21 while i >= 0: 22 tmp = int(num1[i]) + c 23 c = tmp / 10 24 tmp %= 10 25 result.append(str(tmp)) 26 i -= 1 27 while j >= 0: 28 tmp = int(num2[j]) + c 29 c = tmp / 10 30 tmp %= 10 31 result.append(str(tmp)) 32 j -= 1 33 if c: 34 result.append(str(c)) 35 36 return ''.join(result[::-1]) 37 38
221.add-two-numbers-ii
假定用一个链表表示两个数,其中每个节点仅包含一个数字。假设这两个数的数字顺序
排列,请设计一种方法将两个数相加,并将其结果表现为链表的形式。
1 # Definition for singly-linked list. 2 # class ListNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.next = None 6 7 class Solution: 8 # @param l1: the first list 9 # @param l2: the second list 10 # @return: the sum list of l1 and l2 11 def addLists2(self, l1, l2): 12 # Write your code here 13 if not l1: 14 return l2 15 if not l2: 16 return l1 17 l1 = self.reverse(l1) 18 l2 = self.reverse(l2) 19 20 r = self.addLists(l1, l2) 21 return self.reverse(r) 22 23 def reverse(self, head): 24 dummy = ListNode(0) 25 dummy.next = head 26 pre, cur = dummy, head 27 28 while cur: 29 tmp = cur.next 30 cur.next = pre 31 pre = cur 32 cur = tmp 33 34 head.next = None 35 return pre 36 37 def addLists(self, l1, l2): 38 # write your code here 39 rhead = ListNode(0) 40 cur = rhead 41 c = 0 42 while l1 and l2: 43 temp = l1.val + l2.val + c 44 c = temp / 10 45 temp = temp % 10 46 cur.next = ListNode(temp) 47 cur = cur.next 48 l1 = l1.next 49 l2 = l2.next 50 while l1: 51 temp = l1.val + c 52 c = temp / 10 53 temp = temp % 10 54 cur.next = ListNode(temp) 55 cur = cur.next 56 l1 = l1.next 57 while l2: 58 temp = l2.val + c 59 c = temp / 10 60 temp = temp % 10 61 cur.next = ListNode(temp) 62 cur = cur.next 63 l2 = l2.next 64 if c: 65 cur.next = ListNode(c) 66 return rhead.next 67
Onsite II
158.two-strings-are-anagrams
写出一个函数 anagram(s, t)
判断两个字符串是否可以通过改变字母的顺序变成一样的字符串。
1 class Solution: 2 """ 3 @param s: The first string 4 @param b: The second string 5 @return true or false 6 """ 7 def anagram(self, s, t): 8 # write your code here 9 return sorted(list(s)) == sorted(list(t))
386.longest-substring-with-at-most-k-distinct-characters
给定一个字符串,找到最多有k个不同字符的最长子字符串。
重点:保持一个窗口,窗口中的字符串刚好有k个不同字符,加入一个字符时,先从左边删除足够多的元素,使窗口中还是k个字符
1 class Solution: 2 # @param s : A string 3 # @return : An integer 4 def lengthOfLongestSubstringKDistinct(self, s, k): 5 # write your code here 6 if k == 0: 7 return 0 8 if len(s) <= k: 9 return len(s) 10 result = 0 11 i = j = 0 12 hash = {} 13 while j < len(s) and len(hash) < k: 14 if s[j] not in hash: 15 hash[s[j]] = 0 16 hash[s[j]] += 1 17 j += 1 18 if j > 0: 19 j -= 1 20 while j < len(s): 21 result = max(result, j - i + 1) 22 23 if j + 1 < len(s): 24 if s[j + 1] not in hash: 25 while i <= j and len(hash) == k: 26 hash[s[i]] -= 1 27 if hash[s[i]] == 0: 28 del hash[s[i]] 29 i += 1 30 hash[s[j + 1]] = 0 31 hash[s[j + 1]] += 1 32 j += 1 33 return result
171.anagrams
给出一个字符串数组S,找到其中所有的乱序字符串(Anagram)。如果一个字符串是乱序字符串,那么他存在一个字母集合相同,但顺序不同的字符串也在S中。
1 class Solution: 2 # @param strs: A list of strings 3 # @return: A list of strings 4 def anagrams(self, strs): 5 # write your code here 6 hash = {} 7 for s in strs: 8 hash.setdefault(''.join(sorted(s)), []).append(s) 9 result = [] 10 for key in hash: 11 if len(hash[key]) > 1: 12 result.extend(hash[key]) 13 14 return result
Onsite III
479.second-max-of-array
在数组中找到第二大的数
1 import java.util.*; 2 public class Solution { 3 /** 4 * @param nums: An integer array. 5 * @return: The second max number in the array. 6 */ 7 public int secondMax(int[] nums) { 8 Deque<Integer> dq = new LinkedList<>(); 9 dq.addLast(nums[0]); 10 if (nums[1] > nums[0]){ 11 dq.addFirst(nums[1]); 12 } 13 else{ 14 dq.addLast(nums[1]); 15 } 16 for (int i = 2; i < nums.length; i++){ 17 if (nums[i] < dq.getLast()){ 18 continue; 19 } 20 if (nums[i] > dq.getLast() && nums[i] <= dq.getFirst()){ 21 dq.removeLast(); 22 dq.addLast(nums[i]); 23 } 24 if (nums[i] > dq.getFirst()){ 25 dq.removeLast(); 26 dq.addFirst(nums[i]); 27 } 28 } 29 return dq.getLast(); 30 } 31 }
589.connecting-graph
Given n
nodes in a graph labeled from 1
to n
. There is no edges in the graph at beginning.
You need to support the following method:
1. connect(a, b)
, add an edge to connect node a
and node b. 2.
query(a, b)`, check if two nodes are connected
这是图中一些节点动态联通,判断动态联通性的问题。使用并差集算法,详见:http://www.cnblogs.com/zcy-backend/p/6896080.html
1 class ConnectingGraph: 2 3 # @param {int} n 4 def __init__(self, n): 5 # initialize your data structure here. 6 self.father = [_ for _ in xrange(n)] 7 self.size = [1 for _ in xrange(n)] 8 9 def find(self, x): 10 while self.father[x] != x: 11 self.father[x] = self.father[self.father[x]] 12 x = self.father[x] 13 return x 14 15 # @param {int} a, b 16 # return nothing 17 def connect(self, a, b): 18 # Write your code here 19 root_a = self.find(a - 1) 20 root_b = self.find(b - 1) 21 if root_a != root_b: 22 if self.size[root_a] > self.size[root_b]: 23 self.father[root_b] = self.father[root_a] 24 self.size[root_a] += self.size[root_b] 25 else: 26 self.father[root_a] = self.father[root_b] 27 self.size[root_b] += self.size[root_a] 28 29 # @param {int} a, b 30 # return {boolean} true if they are connected or false 31 def query(self, a, b): 32 # Write your code here 33 root_a = self.find(a - 1) 34 root_b = self.find(b - 1) 35 return root_a == root_b
Onsite IV
532.reverse-pairs
在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。给你一个数组,求出这个数组中逆序对的总数。
概括:如果a[i] > a[j] 且 i < j, a[i] 和 a[j] 构成一个逆序对。
注意:插入在最后一个相等元素的后面
1 class Solution: 2 # @param {int[]} A an array 3 # @return {int} total of reverse pairs 4 def reversePairs(self, A): 5 # Write your code here 6 merge = [] 7 result = 0 8 for a in A: 9 result += self.insert(merge, a) 10 return result 11 12 def insert(self, merge, num): 13 if not merge or merge[-1] <= num: 14 merge.append(num) 15 return 0 16 if merge[0] > num: 17 merge.insert(0, num) 18 return len(merge) - 1 19 left, right = 0, len(merge) - 1 20 while left + 1 < right: 21 mid = (right - left) / 2 + left 22 if merge[mid] <= num: 23 left = mid 24 else: 25 right = mid 26 if merge[right] >= num: 27 merge.insert(right, num) 28 return len(merge) - right - 1 29 if merge[left] >= num: 30 merge.insert(left, num) 31 return len(merge) - left - 1 32 33 34
134.lru-cache
1 class Node: 2 def __init__(self, key, val): 3 self.key = key 4 self.val = val 5 self.pre = None 6 self.next = None 7 8 class LRUCache: 9 10 # @param capacity, an integer 11 def __init__(self, capacity): 12 # write your code here 13 self.head = Node(0, 0) 14 self.tail = self.head 15 self.size = 0 16 self.key2node = {} 17 self.capacity = capacity 18 19 # @return an integer 20 def get(self, key): 21 # write your code here 22 if key not in self.key2node: 23 return -1 24 if self.tail == self.key2node[key]: 25 self.tail = self.tail.pre 26 self.key2node[key].pre.next = self.key2node[key].next 27 if self.key2node[key].next: 28 self.key2node[key].next.pre = self.key2node[key].pre 29 self.tail.next = self.key2node[key] 30 self.key2node[key].pre = self.tail 31 self.key2node[key].next = None 32 self.tail = self.tail.next 33 return self.key2node[key].val 34 35 # @param key, an integer 36 # @param value, an integer 37 # @return nothing 38 def set(self, key, value): 39 # write your code here 40 if key not in self.key2node: 41 if self.size < self.capacity: 42 self.tail.next = Node(key, value) 43 self.tail.next.pre = self.tail 44 self.tail = self.tail.next 45 self.key2node[key] = self.tail 46 self.size += 1 47 else: 48 node = self.head.next 49 self.head.next = node.next 50 if node.next: 51 node.next.pre = self.head 52 del self.key2node[node.key] 53 self.tail.next = Node(key, value) 54 self.tail.next.pre = self.tail 55 self.tail = self.tail.next 56 self.key2node[key] = self.tail 57 else: 58 self.key2node[key].val = value 59 self.get(key)