Lintcode

Lakukan tugas rumah & ujian kamu dengan baik sekarang menggunakan Quizwiz!

Loop from end to beginning

Merge Sorted Array

Just loop with 2 index If one array is large, use binary search

Merge Two Sorted Arrays

Classic merge two list If one list is very large, then can use binarySearch

Merge Two Sorted Lists

1. Using heap to store every head Using dummy node to construct the new list 2. D&C, divide into two lists pair, and using merge two list to do it 3. Merge list 2by2, similar to D&C but can do in iterate solution

Merge k Sorted Lists

slow, fast pointers

Middle of Linked List

Binary Search 很随便,找第一个,最后一个,哪个都行

Classical Binary Search

• state: f[i]表示跳到第i个位置的方案总数 • function: f[i] = f[i-1] + f[i-2] • initialize: f[0] = 1 • answer: f[n] // index from 0~n

Climbing Stairs

Using new list to store result Use carry, don't forget to check carry in the end

Add Two Numbers

First reverse Then add Then reverse again

Add Two Numbers II

DP 2-D array int n = A.length; int[][] maxVal = new int[n + 1][m + 1]; maxVal[0][0] = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (j - A[i - 1] >= 0) { maxVal[i][j] = Math.max(maxVal[i - 1][j], maxVal[i - 1][j - A[i - 1]] + V[i - 1]); } else { maxVal[i][j] = maxVal[i - 1][j]; } } } return maxVal[n][m];

Backpack II

D&C Result type contain height and isBalanced

Balanced Binary Tree

Similar to maximum subarray int min = Integer.MAX_VALUE; int max_profit = 0; for (int i = 0; i < prices.length; i++) { min = Math.min(min, prices[i]); max_profit = Math.max(max_profit, prices[i] - min); } Or you can just use greedy

Best Time to Buy and Sell Stock

Greedy, int diff = prices[i+1] - prices[i]; if (diff > 0) { profit += diff; }

Best Time to Buy and Sell Stock II

Using stack first push all left node to it has a cur point to the cur node (not in stack) when hashNext() just check if cur == null next() result is cur, if cur.right != null add all left nodes in cur.right if cur.right == null, just pop from stack

Binary Search Tree Iterator

Classical level order traversal

Binary Tree Level Order Traversal

D& C Result 里包含root2any 和 any2any int passRoot = Math.max(0, left.root2any) + Math.max(0, right.root2any) + root.val; int any2any = Math.max(passRoot, Math.max(left.any2any, right.any2any)); int root2any = Math.max(0, Math.max(left.root2any, right.root2any)) + root.val;

Binary Tree Maximum Path Sum

D&C Math.max(0, Math.max(left, right)) + root.val

Binary Tree Maximum Path Sum II

D & C root在left和right的头上加val 特殊处理叶子结点的情况

Binary Tree Path Sum

1. traversal pass the result 2. D&C, using list.addAll to add left list and right list

Binary Tree Preorder Traversal

double loop use one value row to record current enemy between walls in the current row use cols[] to record current enemy between walls in the current column when reach i = 0 or j = 0 or grid[i][j] = 'W', reset row or col[j], and search until the next wall to count enemy and store in row and col[i] When outer double loop grid[i][j] = '0', check if row + col[j] > max

Bomb Enemy

找出所有的房子,然后再找到所有的空地计算它离所有房子的距离 可以用一个sorted的x list和preSum list of x,来优化计算距离,先通过binary search找到当前点在x的位置,然后用preSum得出距离 这题不能用median的做法,因为不能在有房子的地方建post office

Build Post Office

Classical binary search only one time need the result must be between the start and end

Closest Number in Sorted Array

Greedy 当sum <= 0时重新开始 可以用传统preSum做,但是greedy比较方便

Continuous Subarray Sum

同时保留maxPreSum和minPreSum,反区间采用sum - min的方法酸 要注意的是maxPreSum的时候要处理反区间为空的情况 也可以用greedy来做,想法相似

Continuous Subarray Sum II

1. traversal: have a dummy head and pre, inorder traversal, DoublyListNode cur = new DoublyListNode(root.val); bstToDoublyList(root.left); pre.next = cur; cur.prev = pre; pre = cur; bstToDoublyList(root.right); 2. D&C: design a return type including the beginning and ending of the list

Convert Binary Search Tree to Doubly Linked List

Find mid, then divide & conquer

Convert Sorted List to Balanced BST

Use a hashmap store old_node to new node Iterate through old_list, if old_node or old_node.random not in map, add it in map. Then new_list just simply add from map No extra space 比较麻烦,/*第一遍扫的时候巧妙运用next指针, 开始数组是1->2->3->4 。 然后扫描过程中 先建立copy节点 1->1`->2->2`->3->3`->4->4`, 然后第二遍copy的时候去建立边的copy, 拆分节点, 一边扫描一边拆成两个链表,这里用到两个dummy node。第一个链表变回 1->2->3 , 然后第二变成 1`->2`->3` */

Copy List with Random Pointer

while(node.next != null) { node.val = node.next.val; if(node.next.next == null) { node.next = null; } else { node = node.next; } }

Delete Node in the Middle of Singly Linked List

state: f[i][j] 表示 S的前i个字符中选取T的前j个字符,有多少种方案 • function: f[i][j] = f[i - 1][j] + f[i - 1][j - 1] // S[i-1] == T[j-1] • = f[i - 1][j] // S[i-1] != T[j-1] • initialize: f[i][0] = 1, f[0][j] = 0 (j > 0) • answer: f[n][m] (n = sizeof(S), m = sizeof(T))

Distinct Subsequences

假设最小的次数是X 第i次往上爬X-i+1格 然后问题就变成1+2+......+X大于等于n的最小的X是多少 贪心算法, 每次爬多少都是找的局部最优, 越往上爬剩下的子问题规模越小, 所以全局最优 因为第一个瓶子每爬一下, 第二个瓶子拥有的检查次数都要减少1 因为drop的次数被第一个瓶子多用掉了一次, 所以步长不能超多X-i+1, 如果比X-i+1小 就不是最优

Drop Eggs

state: f[i][j]表示A的前i个字符最少要用几次编辑可以变成B的前j个字符 • function: f[i][j] = MIN(f[i-1][j]+1, f[i][j-1]+1, f[i-1][j-1]) // A[i - 1] == B[j - 1] • = MIN(f[i-1][j]+1, f[i][j-1]+1, f[i-1][j-1]+1) // A[i - 1] != B[j - 1] • initialize: f[i][0] = i, f[0][j] = j • answer: f[n][m]

Edit Distance

Union-Find+HashMap,union的时候要遍历其中一个set乘上对应的factor 或者用graph dfs来做,一个a/b = v相当于a到b的一条边重v,和b到a的一条边重1/v

Evaluate Divisione

Binary Search Remember the graph! Choose the last number as target the condition is the first number less then the target

Find Minimum in Rotated Sorted Array

最坏的必然是O(n), [1,1,1,1,0,1,1,1] 写binarysearch 要和当时的end来比

Find Minimum in Rotated Sorted Array II

Binary Search the condition is A[mid + 1], A[mid] and A[mid - 1]

Find Peak Element

Binary Search find the first item satisfy the condition

First Bad Version

Binary Search Standard search for the first position search

First Position of Target

DP Backpack State: f[i][j] 前i个第i个调整为j时的最小cost Fun: f[i][v] = min(f[i-1][v'] + |A[i]-v|, |v-v'| <= target) Init: f[0][j] = 0, f[i][j] = Integer.MAX_VALUE (i > 0) Res: min(f[n][j]) for (int i = 1; i <= n; i++) { for (int j = 0; j <= 100; j++) { cost[i][j] = Integer.MAX_VALUE; } } for (int i = 1; i <= n; i++) { for (int j = 0; j <= 100; j++) { if (cost[i - 1][j] != Integer.MAX_VALUE) { for (int k = Math.max(0, j - target); k <= Math.min(100, j + target); k++) { cost[i][k] = Math.min(cost[i][k], cost[i - 1][j] + Math.abs(k - A.get(i - 1))); } } } } int res = Integer.MAX_VALUE; for (int i = 0; i <= 100; i++) { res = Math.min(res, cost[n][i]); }

Minimum Adjustment Cost

Until leaf! if(root.left == null && root.right == null) { return 1; } int left = root.left == null?Integer.MAX_VALUE: minDepth(root.left); int right = root.right == null?Integer.MAX_VALUE: minDepth(root.right); return Math.min(left, right) + 1;

Minimum Depth of Binary Tree

• state: f[x][y]从起点走到x,y的min • function: f[x][y] = min(f[x-1][y], f[x][y-1]) + A[x][y] • intialize: f[i][0] = sum(0 - i) f[0][i] = sum(0 - j) • answer: f[n-1][m-1]

Minimum Path Sum

2 pointer 就可以,当快的为null就停下

Nth to Last Node in List

DP 2-D array Backpack IV In each iteration, sum the [i-1][j - k*num[i - 1]] the target should start from 0

Number of Ways to represent N cents

• state: f[i]表示"前i"个字符能否被完美切分 • function: f[i] = OR{f[j]} 其中 j < i && j+1~i is a word • OR 运算的意思 • 假如 j = 0, 1, 3, 5 时满足 j < i && j+1~i is a word • 那么 f[i] = f[0] || f[1] || f[3] || f[5] • initialize: f[0] = true • answer: f[n] • 注意:切分位置的枚举->单词长度枚举 O(NL2) • N: 字符串长度 • L: 最长的单词的长度

Word Break

将n个数看做n个木桩,目的是从某个木桩出发,从前向后,从低往高,看做多能踩多少个木桩。 • state: f[i] 表示(从任意某个木桩)跳到第i个木桩,最多踩过多少根木桩 • function: f[i] = max{f[j] + 1}, j必须满足 j < i && nums[j] <= nums[i] • initialize: f[0..n-1] = 1 • answer: max{f[0..n-1]}

Longest Increasing Subsequence

Don't need to define own Result type if find the node just return node if find both return root

Lowest Common Ancestor

D&C return max(left, right) + 1

Maximum Depth of Binary Tree

Binary Search Compare with neighbor num since mid will never = 0/n, no need to check mid - 1 >= 0 or mid + 1 < n

Maximum Number in Mountain Sequence

Greedy 当sum <= 0时重新开始 可以用传统preSum做,但是greedy比较方便

Maximum Subarray

D & C left, left && right, right

Identical Binary Tree

If the root <= target, successor = root, root = root.left If root > target, root = root.right, successor unchanged

Inorder Successor in Binary Search Tree

Have a new list for insertion sort, then insert node in head one by one

Insertion Sort List

state: f[i][j]表示s1的前i个字符和s2的前j个字符能否交替组成s3的前i+j个字符 function: f[i][j] = (f[i-1][j] && (s1[i-1]==s3[i+j-1]) || (f[i][j-1] && (s2[j-1]==s3[i+j-1]) initialize: f[i][0] = (s1[0..i-1] == s3[0..i-1]) f[0][j] = (s2[0..j-1] == s3[0..j-1]) answer: f[n][m], n = sizeof(s1), m = sizeof(s2)

Interleaving String

1. HashSet 2. Sort and two pointers merge 3. Sort and binary search

Intersection of Two Arrays

最优算法:贪心法,时间复杂度 O(n) 用一个变量保存你最多可以跳多远 • 次优算法:动态规划,时间复杂度 O(n^2) • state: f[i]代表我能否跳到第i个位置 • function: f[i] = OR{f[j]} 其中 j < i && j能够跳到i • 解释:什么是 OR 运算? • 比如满足 j < i && j 能够跳到 i 的 j 有 0, 1, 4, 7 • 那么 f[i] = f[0] || f[1] || f[4] || f[7] • initialize: f[0] = true; • answer: f[n-1]

Jump Game

最优算法:贪心法 O(n) 类似双指针,start, end 初始化为0,从start到end找最远,然后start = end + 1, end = farthest • 次优算法:动态规划 O(n^2) • state: f[i]代表我跳到第 i个位置最少需要几步 • function: f[i] = MIN{f[j]+1} 其中 j < i && j能够跳到i • initialize: f[0] = 0; • answer: f[n-1]

Jump Game II

First Binary search find first >= position Then two pointers go to left and right

K Closest Numbers In Sorted Array

Binary Search <= start = mid > end = mid end == then start ==

Last Position of Target

Slow and fast pointer, if slow can equal to fast then true

Linked List Cycle

Slow fast pointer, after first meet, set slow to head, fast = fast.next, then use the same speed until they meet

Linked List Cycle II

state: f[i][j]表示前i个字符配上前j个字符的LCS的长度 • function: f[i][j] = MAX(f[i-1][j], f[i][j-1], f[i-1][j-1] + 1) // A[i - 1] == B[j - 1] • else f[i][j] = MAX(f[i-1][j], f[i][j-1]) • intialize: f[i][0] = 0 f[0][j] = 0 • answer: f[n][m]

Longest Common Subsequence

state: f[i][j]表示前i个字符配上前j个字符的LCS的长度 • function: f[i][j] = f[i - 1][j - 1] + 1// A[i - 1] == B[j - 1] • else f[i][j] = 0 • intialize: f[i][0] = 0 f[0][j] = 0 • answer: f[n][m]

Longest Common Substring

Use the findkth function Get the start + k/2 value for both array, if val1 < val2 then search start1 + k/2, start2 for k/2, or vice versa O(log (m + n))

Median of two Sorted Arrays

Reverse right half then compare

Palindrome Linked List

• state: f[i]表示前i个字符组成的子串能被分割为最少多少个回文串 • function: f[i] = MIN{f[j]+1}, j < i && j+1 ~ i这一段是一个回文串 • initialize: f[i] = i (f[0] = 0) • answer: f[n] - 1

Palindrome Partitioning II

Using extra two list to record node less than x, and greater or equal to x, then chain them together

Partition List

No need for dummy 相等删next 不相等往后移

Remove Duplicates from Sorted List

if cur.next.val == cur.next.next.val { int val = cur.next.val while (cur.next.next.val == val) { cur.next = cur.next.next

Remove Duplicates from Sorted List II

Using hashset, check cur.next

Remove Duplicates from Unsorted List

check cur.next

Remove Linked List Elements

Slow fast pointer

Remove Nth Node From End of List

Find mid then reverse from mid to end Then start from both start and end, merge two list

Reorder List

classic pre and cur

Reverse Linked List

Do it on the fly, just need to know the current step Need to figure out really clear the relationship between step and cur, it's when cur move to n node, it is step n.

Reverse Linked List II

first check if k > len, k = k % len then slow and fast pointer, remember we want to find the one before the real one

Rotate List

Binary Search Find the first value greater then target

Search Insert Position

Binary Search 1. Treat as a 1-D array 2. find the last start less then target, then binary search

Search a 2D Matrix

Binary Search 先找符合条件的row和col区间 然后在区间里每行再做binary search

Search a 2D Matrix II

两个binary search找边界

Search for a Range

Binary Search Remember the graph! First compare the mid with the end to decide which side the mid is in Then for each side, compare the target with (start, mid) or (end, mid), to decide which side of mid the target is in

Search in Rotated Sorted Array

// 这个问题在面试中不会让实现完整程序 // 只需要举出能够最坏情况的数据是 [1,1,1,1... 1] 里有一个0即可。 // 在这种情况下是无法使用二分法的,复杂度是O(n) // 因此写个for循环最坏也是O(n),那就写个for循环就好了 // 如果你觉得,不是每个情况都是最坏情况,你想用二分法解决不是最坏情况的情况,那你就写一个二分吧。 // 反正面试考的不是你在这个题上会不会用二分法。这个题的考点是你想不想得到最坏情况。

Search in Rotated Sorted Array II

First using pow(2, x) Then binary search

Search in a Big Sorted Array

Merge sort is straightforward, find mid first, then merge sort left and right, then merge Quick sort use 3 tmp list: less then, equal, and greater then, recursively sort less then and greater then, then concat 3 together

Sort List

对preSum排序 减去相邻的preSum得到最小的diff 自定义一个preSum的类比较方便

Subarray Sum Closest

preSum 排序,然后遍历preSum 用binarySearch找到与当前preSum差值符合条件的区域 Note: 两边都需要包括等于的情况!所以某一边需要+1/-1

Subarray Sum II

Dummy head swap cur and pre cur != null && cur.next != null

Swap Nodes in Pairs

Dummy head need to check if n1 and n2 is neighbor Each node need to keep it's pre and next

Swap Two Nodes in Linked List

D & C left, right && right, left

Symmetric Binary Tree

两个binary search找头和尾

Total Occurrence of Target

• state: sum[i][j]从0,0 到 i, j 的最小sm • function: f[i][j] = min(f[i-1][j], f[i - 1][j-1]) + A[j][j] • intialize: f[i][0] = sum(0 - i, A[i][0]) f[i][i] = sum(0 - j, A[i][i]) • answer: min(sum[m - 1][j])

Triangle

D & C (left, left & right, right) || (left, right && right, left)

Tweaked Identical Binary Tree

• state: f[x][y]从起点走到x,y的最短路径 • function: f[x][y] = min(f[x-1][y], f[x][y-1]) + A[x][y] • intialize: f[i][0] = sum(0,0 ~ i,0) f[0][i] = sum(0,0 ~ 0,i) • answer: f[n-1][m-1]

Unique Paths

Same as Unique path Except when init, every thing after obstacle is 0 And in the double loop, if obstacle then 0

Unique Paths II

D&C Result type contains max, min and isValid

Validate Binary Search Tree

swap the unordered neighbor, you can prove that after swap the correct order still hold for the previous series

Wiggle Sort

quick select to find the mid value then put value greater then mid and smaller than mid value into odd and even positions from both ends (or from one end)

Wiggle Sort II

Binary Search Every time calculate piece num as condition find the last satisfy condition

Wood Cut

用一个boolean表示现在是谁,两个index表示当前位置 注意v1长度为0的情况 也可以用两个iterator来做

Zigzag Iterator

ArrayList of iterators iters Once one iterator doesn't have next, remove check iters.size() > 0 for hasNext()

Zigzag Iterator II

3-D array formal i element choose j can sum to t int n = A.length; int[][][] sum = new int[n + 1][k + 1][target + 1]; for (int i = 0; i <= n; i++) { sum[i][0][0] = 1; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= k; j++) { for (int t = 1; t <= target; t++) { if (t - A[i - 1] >= 0) { sum[i][j][t] = sum[i - 1][j][t] + sum[i - 1][j - 1][t - A[i - 1]]; } else { sum[i][j][t] = sum[i - 1][j][t]; } } } } return sum[n][k][target];

k Sum

Two pointer KMP better

strStr


Set pelajaran terkait

41. Battle of Plassey (23 June 1757)

View Set

NCLEX 10000 Integumentary Disorders

View Set

Extra Credit Cumulative IDSC 3001 Quiz

View Set

Das Bruner Test 2 BIOL 348: The Hominids Strike Back BYUH

View Set

Retirement planning Mid and Final

View Set

NU 215 CH29 - assessing child bearing women

View Set

NCE Exam - Lifestyle and Career Development

View Set