Midterm Review
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Midterm Exam
Copyright © 直通硅谷
http://www.zhitongguigu.com/
-
4 questions + 1 bonus question. Finish previous 4 questions first, work on the bonus one if you have time.
-
Time limit is 2 hours, 18:30 - 20:30 PST
-
Copy and paste the NDA above to your txt file and sign. Every candidate should sign the NDA first, if not, the solutions will be regarded as INVALID.
-
All solutions should be replied to govalley.201612@gmail.com
-
All solutions should be submitted in a separate file, named as YourName_midterm.txt.
-
Only one API needs to be implemented for each problem (Java or C++).
-
Comment the ideas and thoughts above your implementation.
- The submitted TXT file should include NDA, 4 + 1 explanations, complexity & implementations.
Midterm Exam
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Sample:
Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
For example,
Given:
s1 = "aabcc",
s2 = "dbbca",
When s3 = "aadbbcbcac", return true.
When s3 = "aadbbbaccc", return false.
Q1
/*
the idea is that...
Time: O(n)
Space: O(n)
*/
public boolean isInterleave(String s1, String s2, String s3) {
}
Midterm Review
- Time Complexity
- Data Structure
- Array, Sort
- LinkedList
- Stack
- Queue
- HashMap
- Algorithms
- Binary Search
- Recursion
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Time Complexity
- Definition
- O
- Best Case, Average Case, Worst Case
- How to calculate
- Master Method
- Maths Deduction
- Recursion
- Solution/Search Space
- From the code
- Important Time Complexity
- Sort: O(nlogn)
- Binary Search: O(logn)
Arrays - add (to end):
- Best: O(1)
- Worst: O(n)
- Average: O(1)
- T(n) = T(n/2) + c = T(n/4) + 2c = .... = T(1) + (logn)*c
- T(n) = T(n-1) + cn = T(n-2) + cn + c(n-1) = ... = T(1) + c(n + (n-1) + ... + 0)
- Combination, Permutation, ...
- Two Pointers
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Array
- Definition
- Same type elements, continuously in memory
- Get any element in constant time.
- Basic Operation
- Get, Add, Remove
- Implementation
- capacity v.s. size -> resize(ensureSize),
- Element[] data
- Two Pointers
- Use two/multiple pointers to iterate the array
- Two Sum, Three Sum, Odd Even Sort, ...
- Get: O(1)
- Add: O(1), O(n)
- Remove: O(1), O(n)
2Sum -> 3Sum -> 4Sum -> ... -> Combination Sum
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Minimum Size Subarray Sum
Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn't one, return 0 instead.
Example Input: [2, 3, 1, 2, 4, 3]; 7
Example Output: 2 ([4, 3])
public int minSubArrayLen(int s, int[] nums) {
int sum = 0;
int min_length = Integer.MAX_VALUE; // Why max?
for (int start = 0, end = 0; start < nums.length; start++) {
while (end < nums.length && sum < s) {
sum += nums[end++];
}
if (sum >= s) {
min_length = Math.min(min_length, end-start);
}
sum -= nums[start];
}
return min_length == Integer.MAX_VALUE ? 0 : min_length;
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Minimum Window Substring
Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
For example,
S = "ADOBECODEBANC"
T = "ABC"
Minimum window is "BANC".
Notes:
- If there is no such window in S that covers all characters in T, return the empty string "".
- You are guaranteed that there will always be only one unique minimum window in S, if exist.
Copyright © 直通硅谷
http://www.zhitongguigu.com/
HashMap Homework
public String minWindow(String s, String t) {
int[] expected = new int[256];
int[] visited = new int[256];
for (int i = 0; i < t.length(); i++) {
expected[(int)t.charAt(i)]++;
}
int end = 0, minLength = Integer.MAX_VALUE, count = 0;
String result = "";
for (int start = 0; start < s.length(); start++) {
while (end < s.length() && count != t.length()) {
visited[s.charAt(end)]++;
if (visited[s.charAt(end)] <= expected[s.charAt(end)]) {
count++;
}
end++;
}
if (count == t.length()) {
if (end - start < minLength) {
minLength = end - start;
result = s.substring(start, end);
}
}
if (expected[s.charAt(start)] > 0) {
visited[s.charAt(start)]--;
if (visited[s.charAt(start)] < expected[s.charAt(start)]) {
count--;
}
}
}
return result;
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
🤔
public String minWindow(String s, String t) {
int[] hm = parseToIntArray(t);
String result = s + t;
int count = t.length();
for (int i = 0, j = 0; i < s.length(); i++) { // move left each outer
for(; count != 0 && j < s.length(); j++) { // run right inner
if (hm[s.charAt(j)] > 0) {
count--;
}
hm[s.charAt(j)]--;
}
if (count == 0) {
result = (j - i) < result.length() ? s.substring(i, j) : result;
}
hm[s.charAt(i)]++;
if (hm[s.charAt(i)] > 0) {
count++;
}
}
return result.length() == (s.length() + t.length()) ? "" : result;
}
private int[] parseToIntArray(String t) {
int[] hm = new int[256];
for (char c : t.toCharArray()) {
hm[c]++;
}
return hm;
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Sort
- Always try to sort first before your algorithm.
- number order, alphabetical order, linked list order, etc.
- Easy for PRUNING
- Two Sum
- Search -> Binary Search
- Permutation
- Combination Sum
- Merge Intervals
- Given a collection of intervals, merge all overlapping intervals.
- [1,3],[2,6],[8,10],[15,18] -> [1,6],[8,10],[15,18]
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Merge Intervals
Given a collection of intervals, merge all overlapping intervals.
Example Input: [1,3],[2,6],[8,10],[15,18]
Example Output: [1,6],[8,10],[15,18]
public List<Interval> merge(List<Interval> intervals) {
if (intervals.size() == 0) {
return new ArrayList<Interval>();
}
Collections.sort(intervals, new Comparator<Interval>(){
@Override
public int compare(Interval a1, Interval a2) {
return a1.start - a2.start; //neg, 0, pos
}
});
ArrayList<Interval> results = new ArrayList<Interval>();
Interval pre = intervals.get(0);
for (int i = 1; i < intervals.size(); i++) {
if (intervals.get(i).start <= pre.end) {
pre.end = Math.max(intervals.get(i).end, pre.end);
} else {
results.add(new Interval(pre.start, pre.end));
pre = intervals.get(i);
}
}
results.add(pre); // Don't forget the last one
return results;
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
class Interval {
int start;
int end;
}
Linked List
- Java variables & data types
- Primitive Type & Reference Type
- Variable Definition/Assignment, Parameter Passing
- Definition
- Linear collection, not continuous, same type
- Accessing one node needs iterating all previous ones.
- Basic Operation
- Get, Add, Remove - O(n)
- Dummy Node
- Remove specialty for head node when structure change may happen.
- Two Pointers
function (ListNode node, int val) {
node.val = 5; // original node changed.
node = new ListNode(5); // no change.
val = 6; // original val will never change.
}
Add: O(1) with tail node.
ListNode dummy = new ListNode(-1);
dummy.next = head
- kth node from the end.
- mid node of the list.
- Whether circle exists
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Linked List
- Programming Tips
- Try to simplify edge cases.
- Keep one node's next before it is changed.
- Check NULL when using while
- while (cur != null) { cur.next }
- while (pre.next != null) { pre.next; pre.next.next; }
- Test Cases
- Make sure you think very clearly before writing code.
- Practicing is the most important for Linked List
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Rotate List
Given a list, rotate the list to the right by k places, where k is non-negative
Example Input: 1->2->3->4->5, 2
Example Output: 4->5->1->2->3
public ListNode rotateRight(ListNode head, int n) {
if (head == null || n == 0)
return head;
ListNode tail = head;
int length = 1;
while (tail.next != null) {
tail = tail.next;
length++;
} // Calculate length of the linked list.
n %= length;
if (n == 0) {
return head;
} // If it is going to do a full rotate, then no need to do.
ListNode newHeadPre = head;
int index = length - n - 1;
while (index-- > 0) {
newHeadPre = newHeadPre.next;
} // Get the previous node of the new head.
tail.next = head;
head = newHeadPre.next;
newHeadPre.next = null;
return head;
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Swap Nodes in Pairs
Given a linked list, swap every two adjacent nodes and return its head.
Example Input: 1->2->3->4
Example Output: 2->1->4->3
Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode pre = dummy;
while (pre.next != null && pre.next.next != null) {
ListNode first = pre.next, second = pre.next.next;
first.next = second.next;
second.next = first;
pre.next = second;
pre = first;
}
return dummy.next;
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Stack & Queue
- Definition
- LIFO v.s. FIFO
- Basic Operation
- size, pop, push, peek
- Implementation
- Based on Array.
- One pointer for Stack, two pointers for Queue.
- When to use Stack & Queue
- Stack: Deep First Search - recursion.
- Queue: Breadth First Search
- Mono-increasing stack
Array -> Queue
Array -> Stack
Stack <-> Queue
- Largest Rectangle in Histogram
- Trapping Rain Water
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Stack & Queue
- Mono-increasing stack
- Keep the elements in an "increasing" order so that previous elements can always extend to current one.
- If new element is larger, push.
- If new element is smaller, pop previous ones until the current one is the largest.
- Keep the elements in an "increasing" order so that previous elements can always extend to current one.
Copyright © 直通硅谷
http://www.zhitongguigu.com/
right: the end of the stack
left: the previous element
Balance Number
Given an array of ints.
Is there a number k in this array that k is larger than all the numbers before it and smaller than all the numbers after it?
[1,2,3,4,5] true
[6,2,3,8,10,9] true
[4,5,3,6] true
[4,3,5,2] false
[1] true
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Extra: return all balance numbers
Balance Number
Copyright © 直通硅谷
http://www.zhitongguigu.com/
public boolean existNumber(int[] nums) {
Stack<Integer> stack = new Stack<>();
int max = Integer.MIN_VALUE;
for (int i = 0; i < nums.length; i++) {
if (nums[i] > max) {
stack.push(nums[i]);
max = nums[i];
} else {
while (!stack.isEmpty() && nums[i] <= stack.peek()) {
stack.pop();
}
}
}
return !stack.isEmpty();
}
- <Key, Value> What to store as K and V
- put(key, value)
- get(key)
- containsKey(key),
- Set<Map.Entry<Key, Value>> entrySet(),
- keySet()
- putAll()
hashcode()
- Collision
equals()
HashMap
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Copyright © 直通硅谷
http://www.zhitongguigu.com/
public int maxPoints(Point[] points) {
if (points == null || points.length == 0) {
return 0;
}
int res = 0, n = points.length;
Map<Pair, Integer> hm = new HashMap<>();
for (int i = 0; i < n; i++) {
hm.clear();
int samePoint = 0, localMax = 0;
for (int j = i + 1; j < n; j++) {
int x = points[i].x - points[j].x;
int y = points[i].y - points[j].y;
if (x == 0 && y == 0) {
samePoint++;
continue;
}
int gcd = GCD(x, y);
Pair p = new Pair(x/gcd, y/gcd); // why?
if (!hm.containsKey(p)) {
hm.put(p, 1);
} else {
hm.put(p, hm.get(p) + 1);
}
localMax = Math.max(localMax, hm.get(p));
}
res = Math.max(res, localMax + samePoint + 1);
}
return res;
}
Max Points on a Line
Given n points on a 2D plane
find the maximum number of points that lie on the same straight line.
Cartesian coordinate system
笛卡尔坐标系(直角坐标系)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
class Pair {
int x, y;
public Pair(int x, int y) {
this.x = x;
this.y = y;
}
public int hashCode() {
String s = x + "," + y;
return s.hashCode();
}
public boolean equals(Object p) {
if (this == p) {
return true;
}
if (p == null || this.getClass() != p.getClass()) {
return false;
}
Pair pair = (Pair) p;
return this.x == pair.x && this.y == pair.y;
}
}
private int GCD(int x, int y) {
if (y == 0) {
return x;
}
return GCD(y, x%y);
}
Max Points on a Line
Given n points on a 2D plane
find the maximum number of points that lie on the same straight line.
Copyright © 直通硅谷
http://www.zhitongguigu.com/
// Greatest Common Divisor
public int GCD(int a, int b) {
if (a == 0 || b == 0) {
return a == 0 ? b : a;
}
if (a == b) {
return a;
}
if (a > b) {
return GCD(a - b, b);
} else {
return GCD(a, b - a);
}
}
// modified version
// work if x and y are both positive
// return negative if y is negative.
// Normal mathematical GCD always return positive.
private int GCD(int x, int y) {
if (y == 0) {
return x;
}
return GCD(y, x % y);
}
// Least Common Multiple
public int LCM(int a, int b) {
return a * b / GCD(a, b);
}
Max Points on a Line
Greatest Common Divisor
GCD 最大公约数
Least Common Multiple
LCM 最小公倍数
Binary Search
- The fastest way to search in sorted array. O(logN)
- Be careful with INFINITE LOOP.
- int begin = 0, end = nums.length; [begin, end)
- int begin = 0, end = nums.length-1; [begin, end]
- Condition to terminate the loop
- Condition for edge cases
- In each loop iteration, there can be only two cases.
- The range of [begin, end]/[begin, end) decrease.
- Jump out of the loop
- Make sure all cases are taken care of before writing code.
- Insert Position
- Search 2D Matrix.
Find Minimum in Rotate Sorted Array
- Comparing mid with begin/end is different.
Copyright © 直通硅谷
http://www.zhitongguigu.com/
public boolean searchMatrix(int[][] matrix, int target) {
int begin = 0, end = matrix.length, mid = 0;
while (begin < end) {
mid = (begin + end) >> 1;
if (matrix[mid][0] == target) {
return true;
} else if (matrix[mid][0] > target) {
end = mid ;
} else {
begin = mid + 1;
}
}
int row = begin - 1;
if (row < 0) return false;
begin = 0;
end = matrix[0].length;
while (begin < end) {
mid = (begin + end) >> 1;
if (matrix[row][mid] == target) {
return true;
} else if (matrix[row][mid] > target) {
end = mid;
} else {
begin = mid + 1;
}
}
return false;
}
Search a 2D Matrix
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
- Integers in each row are sorted from left to right.
- The first integer of each row is greater than the last integer of the previous row.
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Recursion
- Divide problems into smaller instances, solve smaller problems and then solve original problem
- Principles
- How to represent the question
- Parameters that define the question
- Parameters that store the temporary result or state
- Base case
- Recursion rules
- Backtracking
- Pruning strategy
- How to represent the question
-
Recursion is very similar to real thinking.
- Pseudo code can help a lot with these questions.
- Pruning before going into next recursion iteration is very important.
- Permutation II
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Permutation II
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,
[1,1,2] have the following unique permutations:
[ [1,1,2], [1,2,1], [2,1,1] ]
Permutation II
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
dfs(result, intToObj(nums), 0);
return result;
}
private void dfs(List<List<Integer>> result, Integer[] nums, int index) {
// we don't have to wap the last number with itself.
if (index == nums.length - 1) {
result.add(new LinkedList<Integer>(Arrays.asList(nums)));
return;
}
for (int i = index; i < nums.length; i++) {
if (!(i > index && (nums[i] == nums[index]))) {
// (i == index || nums[i] != nums[index])
swap(nums, index, i);
dfs(result, Arrays.copyOf(nums, nums.length), index + 1);
// why not swap back?
}
}
}
private void swap(Integer[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
private Integer[] intToObj(int[] nums) {
Integer[] result = new Integer[nums.length];
for (int i = 0; i < nums.length; i++) {
result[i] = nums[i];
}
return result;
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
古之欲明明德于天下者,先治其国;欲治其国者,先齐其家;欲齐其家者,先修其身;欲修其身者,先正其心;欲正其心者,先诚其意;欲诚其意者,先致其知,致知在格物。
物格而后知至,知至而后意诚,意诚而后心正,心正而后身修,身修而后家齐,家齐而后国治,国治而后天下平。
Recursion
Copyright © 直通硅谷
http://www.zhitongguigu.com/
[GoValley-201612] Midterm Review
By govalley201612
[GoValley-201612] Midterm Review
- 787