Midterm Exam😃
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Given 2 sorted array, find the kth smallest number.
Â
Examples:
Input: [1, 3, 5], [2, 4, 6], 5Â Â Â Â -> Â Â Â Output: 5
Input: [6, 9, 17], [2, 18, 30], 4Â Â -> Â Â Â Output: 17
Â
Interface:
Java: int kthSmall(int[] arr1, int[] arr2, int k);
C++: int kthSmall(vector<int> arr1, vector<int> arr2, int k);
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Everytime, if you do not know the best way, as long as you know a way to solve the problem. Solve it!!!!!
Copyright © 直通硅谷
http://www.zhitongguigu.com/
int kthSmall(int[] arr1, int[] arr2, int k) {
ArrayList<Integer> result = new ArrayList();
for(int i: arr1) {
result.add(i);
}
for(int j: arr2) {
result.add(j);
}
Collections.sort(result);
return result.get(k-1);
}
Merge and Sort: O(nlogn)
Consider Double pointers
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Use double pointers to merge them into a big array instead of using sort.Â
Â
Time complexity O(n)
time complexity :O(k)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
int kthSmall(int[] arr1, int[] arr2, int k) {
int first = 0;
int second = 0;
int[] result = new int[k];
int index = 0;
while(index < k) {
if(first < arr1.length && second < arr2.length) {
if(arr1[first] < arr2[second]) {
result[index++] = arr1[first++];
}
else {
result[index++] = arr2[second++];
}
}
else if(first < arr1.length) {
result[index++] = arr1[first++];
}
else if(second < arr2.length) {
result[index++] = arr2[second++];
}
}
return result[k - 1];
}
A better double pointer
🤔
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Binary Search
A
B
k/2
k/2
A[startA + k/2]
B[startB + k/2]
Compare these two pointers, we can discard some elements and narrow down the search
Binary search :O(logk)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
int kthSmall(int[] arr1, int[] arr2, int k){
return findKthSmallest(arr1, arr2, 0, 0, arr1.length - 1, arr2.length - 1, k);
}
int findKthSmallest(int a[], int b[], int startA, int startB, int endA, int endB, int k){
if(endA - startA > endB - startB) {
return findKthSmallest(b, a, startB, startA, endB, endA, k);
}
if(endA < startA) return b[startB + k - 1];
if(k == 1) return Math.min(a[startA], b[startB]);
int pA = Math.min(endA - startA + 1, k/2);
int pB = k - pA;
if(a[startA + pA - 1] < b[startB + pB - 1]) {
return findKthSmallest(a ,b ,startA + pA, startB, endA, startB + pB, k - pA);
}
else if(a[startA + pA - 1] > b[startB + pB - 1]) {
return findKthSmallest(a ,b ,startA, startB + pB, startA + pA, endB, k - pB);
}
else {
return a[startA + pA - 1];
}
}
Given a collection of numbers C and a number k, return all the combinations of k numbers.Â
Note: There could be duplicates in C, but duplicates are not allowed in the results.
Â
Examples:
Input: [1, 1, 1], 2Â Â Â Â -> Â Â Â Output: [[1, 1]]
Input: [2, 3, 4], 2Â Â Â Â -> Â Â Â Output: [[2, 3], [2, 4], [3, 4]]
Â
Interface:
Java: List<List<Integer>> combination(int[] nums, int k);
C++: vector<vector<int>> combination(vector<int>& nums, int k);Â
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Combination (C, k)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
public static List<List<Integer>> combination(int[] nums, int k) {
List<List<Integer>> results = new ArrayList<>();
if (nums == null || nums.length == 0 || k < 0) {
return results;
}
Arrays.sort(nums);
combine(nums, k, results, new ArrayList<Integer>(), 0);
return results;
}
Sort is important
Combination (C, k)
- If no duplicate
- every number has two options, pick or not.
- Combination(C, k) = Combination(C-nums[i], k-1) + Combination(C-nums[i], k)
- If duplicate
- every number has multiple options, pick 0, 1, 2, ..., m, suppose there are m instances of this number
- Combination(C, k) = Combination(C-nums[i], k) + Combination(C-nums[i], k-1) + ... + Combination(C-nums[i], k-m)
      (C-nums[i] means remove all nums[i] from C.)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Combination (C, k)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
// [[1,1,1],[2,2],[3],[4]]
public static void combine(int[] nums, int k, List<List<Integer>> results,
List<Integer> cur, int index) {
if (k == 0) {
results.add(new ArrayList<Integer>(cur));
return;
}
if (index == nums.length) {
return;
}
int count = 0;
while (index + count < nums.length && nums[index] == nums[index + count]) {
count++;
}
for (int i = 0; i <= count && i <= k; i++) {
for (int j = 0; j < i; j++) {
cur.add(nums[index]);
}
combine(nums, k - i, results, cur, index + count);
for (int j = 0; j < i; j++) {
cur.remove(cur.size() - 1);
}
}
}
Combination (C, k)
- k numbers need to in order, assume the result to be S
- Pick the smallest number (x) for S(k)
- Combination (C, k) -> Combination (C - x, k - 1)
- This can be applied to collections with duplicate and without duplicate.
- With duplicate, don't pick the same number to be the smallest one for multiple times.
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Combination (C, k)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
public static void combine(int[] nums, int k, List<List<Integer>> results,
List<Integer> cur, int index) {
if (k == 0) {
results.add(new ArrayList<Integer>(cur));
return;
}
for (int i = index; i < nums.length - k + 1; i++) {
cur.add(nums[i]);
combine(nums, k - 1, results, cur, i + 1);
cur.remove(cur.size() - 1);
// One chance for every number in every layer
while (i + 1 < nums.length && nums[i] == nums[i + 1]) {
i++;
}
}
}
Given a linked list, check if it is a palindrome. Definition: Palindrome means for a list of element, if its size is n. Then A[i] == A[n-1- i].
Examples:
Input: 1 -> 2 -> 2 -> 1
Output: true
Input: 1 -> 2 -> 3 -> 1
Output: false
Interface:
Java: boolean isPalindrome(ListNode head);
C++: bool isPalindrome(ListNode* head);
Copyright © 直通硅谷
http://www.zhitongguigu.com/
It is similar to reorder linked list
Â
- Partition into two
- Reverse the second
- Compare the first and the new second
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Time complexity: O(n)
Space complexity: O(1)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
public class Solution {
public boolean isPalindrome(ListNode head) {
if(head==null || head.next==null) return true;
ListNode middle = partition(head);
middle = reverse(middle);
while(head!=null && middle!=null) {
if(head.val != middle.val) return false;
head = head.next;
middle = middle.next;
}
return true;
}
private ListNode partition(ListNode head) {
ListNode p = head;
while(p.next!=null && p.next.next!=null) {
p = p.next.next;
head = head.next;
}
p = head.next;
head.next = null;
return p;
}
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
private ListNode reverse(ListNode head) {
if(head==null || head.next==null) return head;
ListNode pre = head;
ListNode cur = head.next;
pre.next = null;
ListNode nxt = null;
while(cur!=null) {
nxt = cur.next;
cur.next = pre;
pre = cur;
cur = nxt;
}
return pre;
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Recursion
Â
two parameters: both are heads
one keeps going to the end
Every time it returns, tell if it is palindrome
Â
time complexity: O(n)
Space complexity: O(1)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
ListNode left;
public boolean isPalindrome(ListNode head) {
left = head;
return recurUtil(head);
}
private boolean recurUtil(ListNode right) {
if (right == null) {
return true;
}
if (right.next != null && !recurUtil(right.next)) {
return false;
}
if (left.val != right.val) {
return false;
}
left = left.next;
return true;
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
// C++
bool recurUtil (ListNode* node, ListNode*& forward) {
/* input list is empty */
if (node == NULL) {
return true;
}
/* only go to the next level when not tail node */
if (node -> next && !recurUtil (node -> next, forward)) {
return false;
}
/* compare node with its counterpart, i.e.,
* the node that's in symmetry position with it
*/
if (node -> val != forward -> val) {
return false;
}
forward = forward -> next;
return true;
}
bool isPalRecur (ListNode* head) {
ListNode *forward = head;
return recurUtil (head, forward);
}
bool isPalindrome (ListNode* head) {
return isPalRecur (head);
}
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Stack
Â
go through the whole linked list
push everything into stack
when popping, just doing the comparison
Â
time complexity: O(n)
Space complexity: O(n)
Copyright © 直通硅谷
http://www.zhitongguigu.com/
// C++
bool isPalWithStack (ListNode *head) {
stack<int> stk;
ListNode *curr = head;
while (curr) {
stk.push (curr -> val);
curr = curr -> next;
}
curr = head;
while (curr) {
if (curr -> val != stk.top()) {
return false;
}
stk.pop();
curr = curr -> next;
}
return true;
}
bool isPalindrome (ListNode* head) {
return isPalWithStack (head);
}
There is a infinite list "A, B, C, ..., Z, AA, AB, ..., AZ, ..., BA, ..., ZZ, AAA, ....". Given an positive integer n, return the nth element in the list.
Â
Examples:
Input: 0 Â Â Â -> Â Â Â Output: A
Input: 26 Â Â -> Â Â Â Output: AA
Input: 701 Â -> Â Â Â Output: ZZ
Â
Interface:
Java: String transform(int n);
C++: string transform(int n);
Copyright © 直通硅谷
http://www.zhitongguigu.com/
There is a infinite list "A, B, C, ..., Z, AA, AB, ..., AZ, BA, ..., ZZ, AAA, ....". Given an positive integer n, return the nth element in the list.
Â
- 10-base to 26-base conversion
- For all n-base numbers, every bit start from zero.
- A == 0?
Copyright © 直通硅谷
http://www.zhitongguigu.com/
10-Base to 26-Base
"A, B, C, ..., Z, AA, AB, ..., AZ, BA, ..., ZZ, AAA, ...."
Copyright © 直通硅谷
http://www.zhitongguigu.com/
A, ..., Z
AA, ..., ZZ
AAA, ..., ZZZ
26
26 * 26
26 * 26 * 26
- Within each block, A can be treated as 0 and Z can be treated as 25. It will be a 10-base to 26-base if we know the position of the number.
10-Base to 26-Base
"A, B, C, ..., Z, AA, AB, ..., AZ, BA, ..., ZZ, AAA, ...."
Copyright © 直通硅谷
http://www.zhitongguigu.com/
public static String transform(int n) {
int baseLength = 1;
int size = 26;
while (size <= n) {
n = n - size; // false correction
size *= 26;
baseLength++;
}
StringBuilder result = new StringBuilder();
for (int i = 1; i <= baseLength; i++) {
result.append((char)('A' + n % 26));
n /= 26;
}
return result.reverse().toString();
}
10-Base to 26-Base
"A, B, C, ..., Z, AA, AB, ..., AZ, BA, ..., ZZ, AAA, ...."
Copyright © 直通硅谷
http://www.zhitongguigu.com/
public String transform(int n) {
StringBuilder sb = new StringBuilder();
while (n >= 0) {
sb.append((char)('A' + n % 26));
if (n < 26) {
break;
}
n = n / 26 - 1;
}
return sb.reverse().toString();
}
// OR modified from 1 -> A
public String transform(int n) {
StringBuilder sb = new StringBuilder();
n++;
while (n > 0) {
n--;
sb.append((char)('A' + n % 26));
n /= 26;
}
return sb.reverse().toString();
}
- new List<>();
- switch case ?
- too long
- no thoughts
- big O
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Midterm Summary
Required
Redo Midterm 1 - 4. Include main method and test cases.
Optional
Copyright © 直通硅谷
http://www.zhitongguigu.com/
Homework 14
[GoValley-201612] Midterm
By govalley201612
[GoValley-201612] Midterm
- 721