leetcode and key points
link to leetcode company repo: https://github.com/youhusky/Leetcode_Company ref to detail solution in chinese: https://leetcode.wang/leetCode-30-Substring-with-Concatenation-of-All-Words.html !!!with time complexity for each problem
记住:
如果把这道题放到真实工程场景里,我会优先考虑数据规模、请求模式、并发情况和可维护性。
在这样的前提下,我选择的解法不仅满足复杂度最优,还能很好地扩展到高并发系统,并支持缓存/分布式等工程优化。
把 LeetCode 题抽象成真实业务:
- 这题像日志流分析?
- 某字段要去重?
- 找最大窗口代表限流?
- DP 表示预算规划?
- BFS 代表任务调度?
不仅说时间复杂度,还说:
- 是否能并行化
- 是否适用于大数据 / 流式处理 / 分布式
- 是否可以“增量计算”:仅重新计算那些依赖于已更改数据的新计算结果,从而在部分数据发生变化时显著节省计算时间。增量计算的常见示例包括电子表格中单元格的自动重算功能,只有直接或间接受影响的单元格才会被更新
- 是否会占用大量内存
- 代码可维护性高不高
你要明确:不是最优算法复杂度,是最优工程实现(可维护、可扩展、可 debug)
- 用缓存?
- 用索引?
- 用 bitset?
- 用分布式?
展示“算法 → 真正工程架构”的迁移能力。
-
业务场景映射
类似于电商系统:用户购物车中有 N 个商品和它们的价格,想知道是否有两个商品加起来恰好等于预算值。
-
分析不同方案的工程代价
解法 A:双指针(排序)
会改变输入,破坏业务数据顺序。不能用在“流式数据”或变化中的列表,❌ 工程成本太高
解法 B:Hash 映射(O(n))
只需要一遍扫描,空间换时间,易 debug,可以增量更新 ✔ 工程最佳实践
-
为什么哈希表是工程上最优?
- 多线程下可以用 ConcurrentHashMap
- 大数据场景可以做分片哈希
- 流式数据中可以渐进构建 hash
- 数据更新时不需要重排数组
- 真实系统优化
- 大量查询情况下可以加 缓存(LRU)
- 超大规模数据可以用 分布哈希 + 一致性哈希
- 若要控制内存,可用 BitMap + BloomFilter 做存在性快速过滤(亿级数据)
-
业务映射
缓存系统的基本模型(Redis、操作系统 Page Cache)。
-
工程代价
- 用 LinkedHashMap — 可维护性最强
- 双向链表 + HashMap — 允许细粒度控制
- 如果高并发 → 用 CAS + SegmentLock
-
为什么选择双向链表 + HashMap?
- O(1) 操作, 高性能, 可扩展到分布式缓存(多层缓存架构)
-
真系统延伸
- 多线程必须考虑锁
- 分布式场景要解决缓存不一致,可引出:Redis + 本地缓存 、 Guava Cache 、 异步刷新
-
业务映射
- 类似 APM(性能监控)中:统计系统中某个时间窗口的最大性能波动值。
-
工程代价
- DP O(n) 是最优,不适合 MapReduce(因为子数组不能任意拆分)
-
为什么选择 Kadane?
-
一遍扫描
-
常数内存
-
易扩展到 streaming
-
可以用于实时监控
- 系统级优化
-
对多节点数据可用 中间结果:prefixMax, suffixMax, totalSum
-
可分治、可分片,支持离线大数据计算(Hadoop/Spark)
Note:
- always start with:
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
dummy.next = head;
use curr to go through list and perform actions
return dummy.next;- to delete a node: 不要跳过所求的node,停在那个node之前,才能skip desired node
- when change order, always set tempNode = x.next, then change the node before x
- always check, head != null
- 虽然时间复杂度都是 O(N),但是迭代解法的空间复杂度是 O(1),⽽递归解法需要堆栈,空间复杂度是 O(N),所以平时更推荐用迭代解法
note:
-
Two pointers:
while(leftPointer< RightPointer) -
Peak and valley:
- when there are a simultaneously increasing or decreasing array
- ex. lc 135-Candy
- can use Stack
- 框架:
public int fn(int[] arr) {
int left = 0, ans = 0, curr = 0;
for (int right = 0; right < arr.length; right++) {
// do logic here to add arr[right] to curr
while (WINDOW_CONDITION_BROKEN) {
// remove arr[left] from curr
left++;
}
// update ans
}
return ans;
}problem: [lc3 - Longest Substring Without Repeating Characters](problems/lc3_longest_substring_without_repeating_char.java)
[lc 76 - Minimum Window Substring](problems/lc76-min-window-substr.java)
lc 239
lc 1040
lc 424
lc 567 !!! interesting sliding window
lc 713 - subarray product less than k
lc 992 - subarrays with k different integers
google - block-with-min-distance
lc 1074 - # of submatricies that sum to target
lc 727 - interesting 2points
lc 1423 - take first k or mid k or last k --> make it a circular array and do sliding window
lc 1031 - max sum of 2 non-overlapping subarrays, prefix sum + sliding window
array-problem summary
array-key points
-
Arrays.toString(another_array[]);
-
Sort: Arrays.sort(nums);
Arrays.sort(intervals, (a, b) -> a[1] - b[1]); -
if have result = List<List>, then add to the result by: result.add(Arrays.asList(x,y, z......));
-
check array is empty: if (array.length == 0 || array == null)
-
Array length: int[] a --> a.length ArrayList b --> b.size() // because arraylist is a collection element
-
if need to return int[][] result, but don't know the size of result yet:
List<int[]> res = new ArrayList<>(); return res.toArray(new int[res.size()][]);
// length can be used for int[], double[], String[] // to know the length of the arrays.
// length() can be used for String, StringBuilder, etc // String class related Objects to know the length of the String
-
type --> Given an unsorted integer array, find the smallest missing positive integer in this range
lc41, 442, 136
-
change from Arraylist to Array
arrayListVar.stream().mapToInt(i -> i).toArray();
- iterative method:
- same as swapping A and B
public ListNode reverseList(ListNode head) {
// 1. Initialize 3 pointers: prev as NULL, curr as head, next as NULL.
ListNode prev = null;
ListNode next = null;
ListNode curr = head;
while (curr != null) {
next = curr.next; Before changing next of current, store next node
curr.next = prev; change next of current, this is where actual reversing happens
prev = curr; Move prev and curr one step forward
curr = next;
}
return prev; In last step, cur = null, and prev stores the last real node
}2.Recursive Method:
- Divide the list in two parts - first node and rest of the linked list.
- Call reverse for the rest of the linked list.
- Link rest to first.
- Fix head pointer
public ListNode reverseList(ListNode head) {
return reverseListInt(head, null);
}
private ListNode reverseListInt(ListNode head, ListNode prev) {
if (head == null)
return prev;
ListNode next = head.next;
head.next = prev;
return reverseListInt(next, head); !!! be careful with the order
}
---------
Node reverseUtil(Node curr, Node prev)
{
/* If last node mark it head*/
if (curr.next == null) {
head = curr;
/* Update next to prev node */
curr.next = prev;
return head;
}
/* Save curr->next node for recursive call */
Node next1 = curr.next;
/* and update next ..*/
curr.next = prev;
reverseUtil(next1, curr);
return head;
} Redo:
lc 430: flatten multilevel double linked list
lc 234: palindrome linked list
prev.next = current.next;
- Always check if node == null
- use 1 at the begining for any recursive/traversal problems
| # | Title | Solution | Complexity | Note | Difficulty |
|---|---|---|---|---|---|
| 1 | 2. add two sums linked list | Java | create sum node, if one list is shorter than the other | Easy | |
| 2 | 61. Rotate List | Java | find pattern, use mod | Medium | |
| 3 | 445. Add Two Numbers II | Java | linked list | Medium | |
| 4 | Maximum difference between two elements such that larger element appears after the smaller number | Java | Time: O(n), Space: O(1) | take the difference with the min element so far. So we remember 1) Maximum difference found so far (max_diff). 2) Minimum number visited so far (min_element). | |
| 5 | Geeks- Remove duplicates from a linked list (both sorted and not sorted) | Java | Time: O(n), Space: O(1) | reverse = swap nearby nodes | Medium |
| 6 | 138. Copy List with Random Pointer | Java | linked list | Medium | |
| 7 | 937. Reorder Data in Log Files | Java | override compare method | Easy | |
| 8 | 380. Insert Delete GetRandom O(1) | Java | hashmap (store (value, index in the array)) + arraylist | Medium | |
| 9 | 430. Flatten a Multilevel Doubly Linked List | Java | recursion OR stack | Medium | |
| 10 | 206. Reverse Linked List | Java | resursion or iterative | Easy | |
| 11 | 234. Palindrome Linked List | Java | resursion | Easy | |
| 12 | 716. Max Stack | Java | treemap + double linked list | Easy | |
| 13 | 238. Product of Array Except Self | Java | create left product array and right product array | Medium | |
| 14 | 219. Contains Duplicate II | Java | set + sliding window, | Easy | |
| 15 | 989. Add to Array-Form of Integer | Java | start from end of input 1 array | Easy | |
| 16 | 950. Reveal Cards In Increasing Order | Java | sorting, stimulation | Medium | |
| 17 | 697. Degree of an Array | Java | hashmap | Easy | |
| 18 | 280. Wiggle Sort | Java | hashmap | Medium | |
| 19 | 767. Reorganize String | Java | hashmap | Medium | |
| 20 | 969. Pancake Sorting | Java | array, find max & reverse twice | Medium | |
| 21 | 84. Largest Rectangle in Histogram | Java | divfide & conquer, stack | Hard | |
| 22 | 859. Buddy Strings | Java | Easy | ||
| 23 | 83. Remove Duplicates from Sorted List | Java | linked list | Easy | |
| 24 | 1441. Build an Array With Stack Operations | Java | stack, | Easy | |
| 25 | 667. Beautiful Arrangement II | Java | array | Medium | |
| 26 | 723. Candy Crush | Java | array | Medium | |
| 27 | 496. Next Greater Element I | Java | stack | Easy | |
| 28 | 907. Sum of Subarray Minimums | Java | stack, with detailed monotonous stack note | Medium | |
| 29 | 901. Online Stock Span | Java | stack, with detailed monotonous stack note | Medium | |
| 30 | 503. Next Greater Element II | Java | stack | Medium | |
| 31 | 1329. Sort the Matrix Diagonally | Java | priority queue or bubble sort | Medium | |
| 32 | 119. Pascal's Triangle II | Java | Easy | ||
| 33 | 665. Non-decreasing Array | Java | Easy | ||
| 34 | 1096. Brace Expansion II | Java | REDO, case by case, python-cartisen product | Hard | |
| 35 | 158. Read N Characters Given Read4 II - Call multiple times | Java | Hard | ||
| 36 | 1313. Decompress Run-Length Encoded List | Java | java- ans.stream().mapToInt(i -> i).toArray() | Hard | |
| 37 | 80. Remove Duplicates from Sorted Array II | Java | 2 pointers | Medium | |
| 38 | 974. Subarray Sums Divisible by K | Java | prefix sum, mod array, ~lc523 | Medium |
(刷到 835)
Notes:
-
when want to optimize space --> from m * n reduce to O(m), declare 2 rows only, prev & current, then use i % 2 to determine which row it is current
boolean[][] dp = new boolean[2][pattern.length() + 1]; dp[text.length() % 2][pattern.length()] = true; dp[i % 2][j] = dp[i % 2][j + 1] || first_match && dp[(i + 1) % 2][j]; -
good practise/optimize question
-
whenever we do sum, subtract, multiply or divide of integers, check overflow!
-
How to find loop:
-
if dp[i][j] depends on dp[i-1][j-1] --> 需要知道比他小的dp for(i = 0, ....) for (j = 0, ....)
-
-
use bit mask to represent state --> more see Math section
我们只要在递归之前做出选择,在递归之后撤销刚才的选择
框架:
result = []
def backtrack(路路径, 选择列列表):
if 满⾜足结束条件:
result.add(路路径)
return
for 选择 in 选择列列表:
做选择
backtrack(路路径, 选择列列表)
撤销选择
如果有list all permutations的情况,比如 17. Letter Combinations of a Phone Number, 则不撤销选择,一直往前走
class Solution {
Map<String, String> phone = new HashMap<String, String>() {{
put("2", "abc");
put("3", "def");
put("4", "ghi");
put("5", "jkl");
put("6", "mno");
put("7", "pqrs");
put("8", "tuv");
put("9", "wxyz");
}};
List<String> output = new ArrayList<String>();
// main method
public List<String> letterCombinations(String digits) {
if (digits.length() != 0)
backtrack("", digits);
return output;
}
public void backtrack(String combination, String next_digits) {
// if there is no more digits to check
if (next_digits.length() == 0) {
output.add(combination);
}
else {
// iterate over all letters which map the next available digit
String digit = next_digits.substring(0, 1);
String letters = phone.get(digit);
for (int i = 0; i < letters.length(); i++) {
String letter = phone.get(digit).substring(i, i + 1);
// append the current letter to the combination
// and proceed to the next digits, substirng(1) means delete the first char in string
backtrack(combination + letter, next_digits.substring(1));
}
}
}其实特别简单,只要稍微修改⼀一下回溯算法的代码即可:
// 函数找到⼀一个答案后就返回 true
bool backtrack(vector<string>& board, int row) {
// 触发结束条件
if (row == board.size()) {
res.push_back(board);
return true;
}
...
for (int col = 0; col < n; col++) {
...
board[row][col] = 'Q';
if (backtrack(board, row + 1))
return true;
board[row][col] = '.';
}
return false;
}!! try RECURSION first tree-problem summary
-
Trie:
- please see tree problems note pad.
- can also be solved by hashmap??
- problem list: lc 421: use search to do XOR lc 208: implement trie lc 336: palindrome lc 1065: lc 720: lc 211: lc 648 lc 677: lc 642: auto-complete system 472. Concatenated Words 1268. Search Suggestions System 1032. stream of characters: store the search words in reverse per question's request
-
Binary search tree: 257: Binary Tree Paths 450: Delete Node in a BST 1373 Maximum Sum BST in Binary Tree 98: BST, in order traversal !!!!!!!!
-
Huffman algorithm --> greedy: 1199 min time to build blocks
| # | Title | Solution | Complexity | Note | Difficulty |
|---|---|---|---|---|---|
| 1 | 257-Binary Tree Paths (print all path in a binary tree) | Java | Time: O(n), Space: O(n) | do level order traversal of tree. While doing traversal, process nodes of different level separately. | easy |
| 2 | 450-Delete Node in a BST | Java | Time: O(height) | 3 cases | medium |
| 3 | 329. Longest Increasing Path in a Matrix | Java | Time: O(mn) | dfs + memorization, high frequence | Hard |
| 4 | 104. Maximum Depth of Binary Tree | Java | Time: O(mn) | dfs + memorization, high frequence | Easy |
| 5 | 226. Invert Binary Tree | Java | dfs or stack or queue | Easy | |
| 6 | 617. Merge Two Binary Trees | Java | recursion or bfs or dfs | Easy | |
| 7 | 96. Unique Binary Search Trees | Java | recursion or dp | Medium | |
| 8 | 95. Unique Binary Search Trees II | Java | !!!!redo, recursion or dp | Medium | |
| 9 | 173. Binary Search Tree Iterator | Java | use stack | Medium | |
| 10 | 421. Maximum XOR of Two Numbers in an Array | Java | Trie | Medium | |
| 11 | 208. Implement Trie (Prefix Tree) | Java | Trie | Medium | |
| 12 | 336. Palindrome Pairs | Java | Trie, not finished for method 2 and 3 | Hard | |
| 13 | 1065. Index Pairs of a String | Java | Trie or startsWith() | Easy | |
| 14 | 720. Longest Word in Dictionary | Java | Trie or startsWith() | Easy | |
| 15 | 692. Top K Frequent Words | Java | Trie, bucket sort, sort | Medium | |
| 16 | 211. Add and Search Word - Data structure design | Java | Trie | Medium | |
| 17 | 648. Replace Words | Java | Trie, use hashmap+trie, hashset | Medium | |
| 18 | 677. Map Sum Pairs Medium | Java | Trie | Medium | |
| 19 | 236. Lowest Common Ancestor of a Binary Tree | Java | binary tree | Medium | |
| 20 | 235. Lowest Common Ancestor of a Binary Search Tree | Java | binary tree | Easy | |
| 21 | 102. Binary Tree Level Order Traversal | Java | binary tree | Medium | |
| 22 | 297. Serialize and Deserialize Binary Tree | Java | binary tree | Hard | |
| 23 | 113. Path Sum II | Java | binary tree, dfs, start from root & end at leaf | Medium | |
| 24 | 437. Path Sum III | Java | !!!prefix sum hashmap, start & end at any node | Easy | |
| 25 | 117. Populating Next Right Pointers in Each Node II | Java | binary tree, dfs, start from root & end at leaf | Medium | |
| 26 | 1145. Binary Tree Coloring Game | Java | find pattern, compare max(left, right, parent) and n / 2 | Medium | |
| 27 | Geeks-Find maximum level sum in Binary Tree | Java | Time: O(n), Space: O(n) | do level order traversal of tree. While doing traversal, process nodes of different level separately. | |
| 28 | Geeks-Maximum width of a binary tree | Java | 1) Level Order Traversal with Queue 2) Using Preorder Traversal | ||
| 29 | Geeks-Print path from root to a given node in a binary tree | Java | O(n) | use arraylist to store path, remember to delete elem in array if not found! | |
| 30 | Geeks-Sorted order printing of a given array that represents a BST | Java | O(n) | 1) use arraylist to store path, remember to delete elem in array if not found! 2)in array, the node's at position x, then its left child is at 2x+1, its right child is at 2x+2 | |
| 31 | Geeks-Prime in a subtree | Java | twitter OA | ||
| 32 | Geeks-Construct treee with inorder & level order | Java | O(n^2) | Leetcode 106. | |
| 33 | Geeks-Construct Tree from given Inorder and Preorder traversals | Java | !!! hard Leetcode 105. | ||
| 33 | 105.Construct Tree from given Inorder and Preorder traversals | Java | 1) use hashmap 2)stack + hashmap 3) use stack + set: | Medium | |
| 34 | Geeks - Find the maximum sum leaf to root path in a Binary Tree | Java | recursion | ||
| 35 | 124. Binary Tree Maximum Path Sum (don't need to pass root) | Java | recursion, keep global variable maxValue and keep updating it | Hard | |
| 36 | Geeks - Maximum sum of nodes in Binary tree such that no two are adjacent | Java | recursion or pair | ||
| 37 | 642. Design Search Autocomplete System | Java | Trie | Hard | |
| 38 | 212. Word Search II | Java | Trie | Hard | |
| 39 | 572. Subtree of Another Tree | Java | String builder, or recursively check each node, need to check isSubtree(s.left, t) OR isSubtree(s.right, t) | Easy | |
| 40 | 472. Concatenated Words | Java | dp(very neat!) or dfs + Trie | Hard | |
| 41 | 99. Recover Binary Search Tree | Java | inorder traversal + find misplaced pair | Hard | |
| 42 | 545. Boundary of Binary Tree | Java | REDO! preorder, (weird problem) | Medium | |
| 43 | 1268. Search Suggestions System | Java | Trie or binary search with treemap~ | Medium | |
| 44 | 1110. Delete Nodes And Return Forest | Java | recursion | Medium | |
| 45 | 222. Count Complete Tree Nodes | Java | recursion | Medium | |
| 46 | 951. Flip Equivalent Binary Trees | Java | recursion, canonical representaion (left child is smaller than the right) | Medium | |
| 47 | 1032. Stream of Characters | Java | Trie | Hard | |
| 48 | 543. Diameter of Binary Tree | Java | recursion | Easy | |
| 49 | 979. Distribute Coins in Binary Tree | Java | recursion | Medium | |
| 50 | 671. Second Minimum Node In a Binary Tree | Java | recursion or bfs | Easy | |
| 51 | 110. Balanced Binary Tree | Java | recursion or iterative, subtrees diff by 1 | Easy | |
| 52 | 1373. Maximum Sum BST in Binary Tree | Java | need to store: is_BST, sum, min, max | Hard | |
| 53 | 98. Validate Binary Search Tree | Java | recursion or use stack | Medium | |
| 55 | 94. Binary Tree Inorder Traversal | Java | recursion or use stack | Medium | |
| 56 | 230. Kth Smallest Element in a BST | Java | recursion or use stack | Medium | |
| 57 | 1339. Maximum Product of Splitted Binary Tree | Java | recursion | Medium | |
| 58 | 1367. Linked List in Binary Tree | Java | recursion or KPM | Medium | |
| 59 | 107. Binary Tree Level Order Traversal II | Java | dfs or bfs | Easy | |
| 60 | 563. Binary Tree Tilt | Java | recursion | !! Easy | |
| 61 | 1372. Longest ZigZag Path in a Binary Tree | Java | dfs | Medium | |
| 62 | 1199. Minimum Time to Build Blocks | Java | Huffman algorithm | Hard | |
| 63 | 108. Convert Sorted Array to Binary Search Tree | Java | recursion or BFS | Easy | |
| 64 | 101. Symmetric Tree | Java | recursion OR queue (iterative) | Easy | |
| 65 | 111. Minimum Depth of Binary Tree | Java | dfs or bfs | Easy | |
| 66 | 112. Path Sum | Java | dfs or bfs | Easy | |
| 67 | 129. Sum Root to Leaf Numbers | Java | recursion or use stack, preorder | Medium | |
| 68 | 666. Path Sum IV | Java | recursion or use stack, preorder | Medium |
(刷到1130)
-
Island problems:
- use dfs / bfs / union find
- when reach a '1', go to dfs function
- in dfs: 1) check for validility, 2) mark current position to a 0, 3) call dfs on neigbors
- water flood fill lc 1254: num of closed islands lc 695: max area of island
-
Double end bfs: lc 752: open the lock
have 2 hashSet: begin, end The whole process is like: Running BFS in 'begin' set -----> Create a new set 'temp' to store the value -----> begin = temp -----> 'begin'(is 'temp' now) and 'end' exchange value ------> (next loop) Running BFS in 'end'(is now 'begin')
Caution: for 2 end bfs, need to maintain a global set visited in order to not let 2 ends into looping
-
represent visited/unvisited node state: use int mask
for (int next : graph[node.id]) Node nextNode = new Node(next, node.mask | (1 << next));
Interesting binary search problems:
lc 1011
lc 875
lc 774
lc 410 --> value
lc 74
lc 1231
lc 162 - Find Peak Element - Medium
Tricks:
-
Sorting Algorithm:
Arrays.sort() used to sort elements of a array. Collections.sort() used to sort elements of a collection.
For primitives, Arrays.sort() uses dual pivot quicksort algorithms.
-
Searching Algorithm:
Arrays.binarySearch(array,key)) used to apply binary search on an sorted array. Collections.binarySearch() used to apply binary search on a collection based on comparators.
int i = Arrays.binarySearch(dp, 0, len, num); // search in entire array
int i = Arrays.binarySearch(int[] arr, int fromIndex, int toIndex, int key) // in subarray
if (i < 0) {
i = -(i + 1);
}注意:
-
”maximize the minimum" or "minimize the maximum“ 就是binary search解法!
-
三种情况不同的只需要改两行:
-
- 找到target的时候,左侧边界right = mid - 1;右侧边界left = mid + 1
-
- 最后的返回条件,左侧边界检查左侧越界情况
左侧
if (left >= nums.length || nums[left] != target) return -1,
右侧
if (right < 0 || nums[right] != target) return -1;
if you use while (lo <= hi) you use lo=mid+1 and hi=mid-1
if you use while (lo < hi) you use lo = mid+1 and hi=mid- 最后 return left 还是 right,取决于:循环结束时,哪一个指针“一定满足你要找的条件”
- 二分不是在找“位置”,而是在找 第一个 / 最后一个满足某个 predicate 的点。
- 第一个满足条件的, return left
- 最后一个满足条件的, return right
🟢 例 1:LeetCode 704(标准找值
- 在一个已排序(升序)的整数数组 nums 中搜索一个目标值 target,如果找到,返回其索引;如果没找到,返回 -1
while (l <= r) {
int mid = l + (r - l) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < target)
l = mid + 1;
else
r = mid - 1;
}
return -1;👉 这是“精确命中”,找不到就 -1,不涉及 return left/right
🟡 例 2:第一个 ≥ target(Lower Bound) nums = [1,2,4,4,5],target = 4,答案是 index = 2
while (l <= r) {
int mid = l + (r - l) / 2;
if (nums[mid] >= target) {
r = mid - 1;
} else {
l = mid + 1;
}
}
return l;循环结束时,l 指向第一个满足条件的:
r | l
↓
[ < target ][ >= target ]
🟡 例 3:最后一个 ≤ target(Upper Bound)
- return r?
结束状态:
[ <= target ][ > target ]
↑
r
👉 r 是 最后一个合法的
🔴 例 4:二分答案(最重要的面试场景)
典型题:
-
Capacity To Ship Packages
-
Koko Eating Bananas
-
Minimum Speed / Maximum Value
LeetCode 875 — Koko Eating Bananas
问题:
- piles = [3, 6, 7, 11], h = 8 小时,每小时吃 k 根香蕉,问:最小的 k 是多少?
🔍 我们二分的不是数组,而是「答案空间」
k = 1 → 吃得太慢 ❌
k = 2 → ❌
k = 3 → ❌
k = 4 → ✅
k = 5 → ✅
k = 6 → ✅
👉 明显单调,所以可以二分:
false false false true true true
1️⃣ 搜索区间
- left = 1
- right = max(piles) = 11
2️⃣ 判定函数
boolean canEat(int k) {
int hours = 0;
for (int p : piles) {
hours += (p + k - 1) / k; // 向上取整
}
return hours <= h;
}完整二分过程(逐步动画)
🟢 Step 1
- l = 1, r = 11
- mid = 6
- 算 canEat(6):总 = 6 ≤ 8 ✅
👉 mid 可行 → 向左找更小的: r = mid - 1 = 5
🟢 Step 2
- l = 1, r = 5
- mid = 3
3/3=1 6/3=2 7/3=3 11/3=4 总 = 10 > 8 ❌
👉 不可行 → 速度太慢 → 向右: l = mid + 1 = 4
🟢 Step 3
- l = 4, r = 5
- mid = 4
3/4=1 6/4=2 7/4=2 11/4=3 总 = 8 ≤ 8 ✅
👉 可行 → 再试更小
r = mid - 1 = 3
🛑 结束条件 l = 4, r = 3 l > r → loop ends
为什么最后 return left?
k: 1 2 3 4 5 6 ...
❌ ❌ ❌ ✅ ✅ ✅
↑
left
right = 3 → 最后一个 ❌
left = 4 → 第一个 ✅
👉 题目要的是:最小可行解, 所以 return left; // 4
- 最基本的二分查找算法
因为我们只需找到⼀个 target 的索引即可 所以当 nums[mid] == target 时可以立即返回
int binary_search(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while(left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
}
else if (nums[mid] > target) {
right = mid - 1;
}
else if(nums[mid] == target) { // 直接返回
return mid;
}
}
// 直接返回
return -1;
}-
寻找左侧边界的二分搜索
因为我们需找到 target 的最右侧索引 所以当 nums[mid] == target 时不要立即返回 ⽽要收紧左侧边界 以锁定右侧边界
int left_bound(int[] nums, int target) {
int left = 0,
right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
// 搜索区间变为 [mid+1, right]
left = mid + 1;
}
else if (nums[mid] > target) {
// 搜索区间变为 [left, mid-1]
right = mid - 1;
}
else if (nums[mid] == target) {
// 收缩右侧边界,找到 target 时不要⽴即返回,⽽是缩小「搜索区间」的上界 right ,在区间 [left, mid) 中 继续搜索,即不断向左收缩,达到锁定左侧边界的目的
right = mid - 1;
}
}
// 检查出界情况
if (left >= nums.length || nums[left] != target)
return -1;
return left;
}- 寻找右侧边界的二分查找
int right_bound(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
}
else if (nums[mid] > target) {
right = mid - 1;
}
else if (nums[mid] == target) { // 这⾥改成收缩左侧边界即可
left = mid + 1;
}
}
// 这⾥改为检查 right 越界的情况,⻅见下图
if (right < 0 || nums[right] != target)
return -1;
return right;
}凡是符合单调性的,都可以用binary search
left & right为weight,比如left = array里最大的重量,right = 总重,binary search一个合适的重量mid such that满足某个条件,比如五天内运完所有货物
- Capacity To Ship Packages Within D Days - Medium
- Minimum Number of Days to Make m Bouquets
- Divide Chocolate
🟢 关键观察
容量越大,越容易在 D 天内运完;容量越小,越难。 👉 符合 单调性,所以可以用 二分搜索。
在算法题里,单调性通常指:
当某个参数 变大/变小 时,问题的可行性结果不会“跳来跳去”,而是保持 单调变化。
也就是说:如果参数满足某个条件,那么更大的参数(或更小的参数)也一定满足(或一定不满足)。
🟢 二分范围
最小容量 = max(weights)(至少能运得动最重的包裹)。
最大容量 = sum(weights)(一次性运完所有包裹)。
🟢 检查函数(贪心模拟)
给一个候选容量 cap,模拟装货过程:
从第一个包裹开始,依次累加重量;
如果加上下一个包裹超出 cap,则开新的一天(day++);
最后检查天数是否 <= D。
如果 day <= D,说明容量够大,可以尝试减小; 否则说明容量太小,需要增加。
public int shipWithinDays(int[] weights, int D) {
int beg=0;
int end=0;
for(int w:weights){
beg = Math.max(beg,w);
end +=w;
}
int ans = 0;
while(beg <= end){
int mid = beg + (end-beg)/2;
int days = findDays(weights,mid);
// with current mid, use less days then required, can further reduce capacity
if(days <= D){
end=mid-1;
ans = mid;
}
else{
beg=mid+1;
}
}
return ans;
}
public int findDays(int a[],int capacity){
int days=1;
int sum=0;
for(int x:a){
sum=sum+x;
//一天之内装不完,days++ 作为新的单独一天
if(sum > capacity){
days++;
sum=x;
}
}
return days;
}similar question: 410. Split Array Largest Sum - Hard
Note: binary search can be optimized by setting a close bound for left and right
//最少一小时吃了1个香蕉,最后+1是margin of error
int low = (int)((totalBanana-1)/hours) + 1;
//如果length中每一个pile用一个小时吃,也要用这么多
int high = (int)((totalBanana-length)/(hours-length+1)) + 1;| # | Title | Solution | Complexity | Note | Difficulty |
|---|---|---|---|---|---|
| 1 | 33-Search in Rotated Sorted Array(binary search) | Java | O(log n) | need to know where is the "real start" of the array | medium |
| 2 | 34-Find First and Last Position of Element in Sorted Array | Java | O(log n) | !!! do 2 binary search | medium |
| 3 | 21. Merge Two Sorted Lists | Java | Easy | ||
| 4 | 23. Merge k Sorted Lists | Java | redo! node is hard | Hard | |
| 5 | 35. Search Insert Position | Java | edge case | Easy | |
| 6 | 378. Kth Smallest Element in a Sorted Matrix | Java | Heap or Binary search, also #240 | Medium | |
| 7 | 373. Find K Pairs with Smallest Sums | Java | Heap !! method 3 doesn't use priority queue | Medium | |
| 8 | 1011. Capacity To Ship Packages Within D Days | Java | Binary search, airbnb-oa4 | Medium | |
| 9 | 875. Koko Eating Bananas | Java | Binary search, airbnb-oa4 | Medium | |
| 10 | 774. Minimize Max Distance to Gas Station | Java | Binary search | Hard | |
| 11 | 410. Split Array Largest Sum | Java | !! redo. Binary search on sum of subarry & push, DFS+ memorization, backtrack | Hard | |
| 12 | geeks-K’th Smallest Element in Unsorted Array | Java | worst case: linear | divide to 5 list | Medium |
| 13 | 315. Count of Smaller Numbers After Self | Java | merge sort, BST, binary indexed tree | Hard | |
| 14 | 74. Search a 2D Matrix | Java | binary search on value | Medium | |
| 15 | 363. Max Sum of Rectangle No Larger Than K | Java | O(n * n * (m) * lgm) n = col size, m = row size | treeset, 3 loops, prefix-sum | Hard |
| 16 | 973. K Closest Points to Origin | Java | O(n), O(N*log k) | quick sort & min-heap | Medium |
| 17 | 240. Search a 2D Matrix II | Java | O(m+n) | start from bottom left, or divide & conquer | Medium |
| 18 | 295. Find Median from Data Stream | Java | O(log n) | 2 heap(one large,one small) | Hard |
| 19 | 347. Top K Frequent Elements | Java | O(n) | bucket sort, tree map, min heap | Medium |
| 20 | 140. Word Break II | Java | dp or dfs+memorization | Hard | |
| 21 | 759. Employee Free Time | Java | O(c*log n) | sweep line or PQ stored | Hard |
| 22 | 1268. Search Suggestions System | Java | Trie or binary search with treemap~ | Medium | |
| 23 | 1231. Divide Chocolate | Java | 神奇的binary search | Hard | |
| 24 | 75. Sort Colors | Java | quick sort | Medium | |
| 25 | 354. Russian Doll Envelopes | Java | quick sort | Hard | |
| 26 | 464. Can I Win | Java | DFS + memo, key is that opponent always lose | Medium | |
| 27 | 162. Find Peak Element | Java | binary search, math always find a peak on left if a[mid] > a[mid+1] | Medium | |
| 28 | 704. Binary Search | Java | binary search | Easy |
Tricks:
-
Calculating the most significant digit of number N:
double K = Math.log10(N); K = K - Math.floor(K); int X = (int)Math.pow(10, K); X will be the most significant digit.
-
Calculating the # of digits directly:
No. of digits in N = Math.floor(Math.log10(N)) + 1;
-
checking for a prime number: returns true if this BigInteger is probably prime(with some certainty), false if it’s definitely composite.
BigInteger.valueOf(1235).isProbablePrime(1)
-
XOR:
If we take XOR of zero and some bit, it will return that bit a⊕0=a If we take XOR of two same bits, it will return 0 a⊕a=0 a⊕b⊕a = (a⊕a)⊕b = 0⊕b = bpublic int singleNumber(int[] nums) { int a = 0; for (int i : nums) { a ^= i; } return a; }
-
bit mask (lc 1349)
-
-
use (1 << x) to set the x-th bit to one, ex. 1<< 2 = 2^2 = 4, 1<<3 = 2^3 = 8, ...
Thus, we can use an int variable int mask to show the status of x workers
- check if the j-th worker is already being processed: if (mask & (1<<j)) == 0)
2)set the j-th worker as 'already processed': mask | (1 << j)
3)unset j-th bit
used &= ~(1 << j) // (1<<3) = 100, ~(1 << 3) = 011, used = used & 011 // ex. used = 1100 now, 1100 & 011 = 1000, now we unset the 3rd bit to 0
-
-
- We can use (x >> i) & 1 to get i-th bit in state x, where >> is the right shift operation. If we are doing this in an if statement (i.e. to check whether the i-th bit is 1), we can also use x & (1 << i), where the << is the left shift operation.
-
- We can use (x & y) == x to check if x is a subset of y. The subset means every state in x could be 1 only if the corresponding state in y is 1.
-
- We can use (x & (x >> 1)) == 0 to check if there are no adjancent valid states in x.
-
-
store pre-compute count in an array
for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) validRows[i] = (validRows[i] << 1) + (seats[i][j] == '.' ? 1 : 0);
-
-
bit problem (lots of time only care about last digit, don't store entire number to avoid overflow): lc 190 --> reverse unsigned bits lc 1349 --> use bit and mask to check for upper left position, upper right position lc 868 --> binary gap
-
Bitwise operator:
Bitwise operator works on bits and performs bit-by-bit operation.
Assume if a = 60 and b = 13; now in binary format they will be as follows −
a = 0011 1100
b = 0000 1101
a&b = 0000 1100
a|b = 0011 1101
a^b = 0011 0001
~a = 1100 0011
-
& (bitwise and) Binary AND Operator copies a bit to the result if it exists in both operands.
(A & B) will give 12 which is 0000 1100 -
| (bitwise or)
Binary OR Operator copies a bit if it exists in either operand. (A | B) will give 61 which is 0011 1101 -
^ (bitwise XOR) Binary XOR Operator copies the bit if it is set in one operand but not both.
(A ^ B) will give 49 which is 0011 0001 -
~ (bitwise compliment)
Binary Ones Complement Operator is unary and has the effect of 'flipping' bits. (~A ) will give -61 which is 1100 0011 in 2's complement form due to a signed binary number. -
<< (left shift) Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand. A << 2 will give 240 which is 1111 0000
-
(right shift)
Binary Right Shift Operator. The left operands value is moved right by the number of bits specified by the right operand.
A >> 2 will give 15 which is 1111 -
(zero fill right shift) Shift right zero fill operator. The left operands value is moved right by the number of bits specified by the right operand and shifted values are filled up with zeros.
A >>>2 will give 15 which is 0000 1111 -
ex. flip 0 to 1, and 1 to 0 int x ^ 1 a = 0011 1100 --> a^1 = 1100 0011
| # | Title | Solution | Complexity | Note | Difficulty |
|---|---|---|---|---|---|
| 1 | 593-Valid Square | Java | do level order traversal of tree. While doing traversal, process nodes of different level separately. | easy | |
| 2 | 400-Nth Digit | Java | minus single digits, double digits, etc. | easy | |
| 3 | 4-Median of Two Sorted Arrays | Java | lots of math involved, redo when have time | hard | |
| 4 | 6. ZigZag Conversion | Java | find pattern, use increment & decrement variables, string buffers | medium | |
| 5 | 7. Reverse Integer | Java | use %10 | Easy | |
| 6 | 9. Palindrome Number | Java | tricky special case, consider # end with 0, consider loop condition & comparison | Easy | |
| 7 | 31. Next Permutation | Java | find pattern for next greater num | Medium | |
| 8 | 60. Permutation Sequence | Java | redo! permiutation, calculate group | Medium | |
| 9 | 264. Ugly Number II | Java | dp or heap, find pattern | Medium | |
| 10 | 166. Fraction to Recurring Decimal | Java | dp or heap, find pattern | Medium | |
| 11 | Geeks - Find position of the only set bit | Java | dp or heap, find pattern | Medium | |
| 12 | Geeks - Binary representation of a given number | Java | bit | Medium | |
| 13 | Geeks - find set bits | Java | bit | Medium | |
| 14 | 852. Peak Index in a Mountain Array | Java | dp or heap, find pattern | Easy | |
| 15 | Geeks - Sum of all Subarrays | Java | math, count occurance of each element | Medium | |
| 16 | 1007. Minimum Domino Rotations For Equal Row | Java | observe, countA[i] + countB[i] - same[i] = n | Medium | |
| 17 | 279. Perfect Squares | Java | observe, countA[i] + countB[i] - same[i] = n | Medium | |
| 18 | Geeks - Convex Hull - find convex polygon to contain all points | Java | greedy, pick the most "counter-clockwise" point | Medium | |
| 19 | Geeks - Sum of absolute differences of all pairs in a given array | Java | Math, sum = sum + (i*a[i]) – (n-1-i)*a[i] | Medium | |
| 20 | 1277. Count Square Submatrices with All Ones | Java | observe, countA[i] + countB[i] - same[i] = n | Medium | |
| 21 | 793. Preimage Size of Factorial Zeroes Function | Java | exactly K = (trailing zero < K) - (trailing zero < K-1) | Hard | |
| 22 | 273. Integer to English Words | Java | array with constants English words | Hard | |
| 23 | 957. Prison Cells After N Days | Java | stimulation --> store seen ones --> find pattern, 直接mod | Medium | |
| 24 | 456. 132 Pattern | Java | stimulation --> store seen ones --> find pattern, 直接mod | Medium | |
| 25 | 866. Prime Palindrome | Java | check odd length palindrome (even length is a multiple of 11) | Medium | |
| 26 | 1041. Robot Bounded In Circle | Java | check odd length palindrome (even length is a multiple of 11) | Medium | |
| 27 | 939. Minimum Area Rectangle | Java | check for rectangles, use encoded, sort by row & hashmap | Medium | |
| 28 | 1025. Divisor Game | Java | math, done by deduction, return n%2 == 0 | Easy | |
| 29 | 136. Single Number | Java | use XOR to achieve linear time & no extra memory --> XOR all bits | Easy | |
| 30 | 1227. Airplane Seat Assignment Probability | Java | Math | Medium | |
| 31 | 415. Add Strings | Java | Easy | ||
| 32 | 466. Count The Repetitions | Java | need to find the pattern | Hard | |
| 33 | 1012. Numbers With Repeated Digits | Java | dp + math | Hard | |
| 34 | 902. Numbers At Most N Given Digit Set | Java | math | Hard | |
| 35 | 750. Number Of Corner Rectangles | Java | Medium | ||
| 36 | 190. Reverse Bits | Java | bits | Easy | |
| 37 | 229. Majority Element II | Java | Medium | ||
| 38 | 1058. Minimize Rounding Error to Meet Target | Java | Very nice greedy solution! DP --> generate all combinations | Medium | |
| 39 | 902. Numbers At Most N Given Digit Set | Java | math | Hard | |
| 40 | [564. Find the Closest Palindrome]https://leetcode.com/problems/find-the-closest-palindrome/) | Java | math, corner case | Hard | |
| 41 | 868. Binary Gap | Java | bits | Easy | |
| 42 | 693. Binary Number with Alternating Bits | Java | bits | Easy | |
| 43 | 1018. Binary Prefix Divisible By 5 | Java | bits | Easy | |
| 44 | 1363. Largest Multiple of Three | Java | mod | Hard |
| # | Title | Solution | Complexity | Note |
|---|---|---|---|---|
| 1 | Print ‘K’th least significant bit of a number | Java | use shift and AND |
V put(K key, V value):插入键值对。如果 Key 已存在,覆盖旧值并返回旧值。
V get(Object key):获取 Key 对应的值,不存在则返回 null。
V remove(Object key):根据 Key 删除键值对。
boolean containsKey(Object key):判断是否包含某个 Key。
int size():返回当前键值对的数量。
void clear():清空 Map。
-
用法:map.getOrDefault("ID_123", 0);
-
价值:避免了 null 指针检查,直接提供备选方案。
computeIfAbsent(K key, Function mappingFunction)
-
核心作用是:“如果指定的键(Key)不存在或值为 null,则通过给定的映射函数计算一个值,并将其放入 Map 中,最后返回这个值。”
-
场景:初始化集合。例如 map.computeIfAbsent("list", k -> new ArrayList<>()).add(item);
V value = map.computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction);场景 A:初始化集合(构建多值 Map)
这是最常见的用法。例如,将学生按班级分组:
Map<String, List<String>> classMap = new HashMap<>();
// 逻辑:如果班级不存在,新建一个 ArrayList;然后把学生加进去
classMap.computeIfAbsent("一班", k -> new ArrayList<>()).add("张三");
classMap.computeIfAbsent("一班", k -> new ArrayList<>()).add("李四");
// 结果:一班 -> [张三, 李四]如果value是一个priority queue:
HashMap<String, PriorityQueue<Food>>cuisineMap = new HashMap<>();
cuisineMap.computeIfAbsent(cuisines[i], k ->
new PriorityQueue<>((a, b) -> {
if (a.rating != b.rating) return b.rating - a.rating; // higher rating first
return a.name.compareTo(b.name); // lexicographically smaller first
})
).add(food);
场景 B:本地缓存(Cache) 作为简单的内存缓存,避免重复计算:
Map<Integer, Integer> fibCache = new ConcurrentHashMap<>();
public int fibonacci(int n) {
if (n <= 1) return n;
return fibCache.computeIfAbsent(n, k -> fibonacci(k - 1) + fibonacci(k - 2));
}如果 Value 是简单的常量,使用 putIfAbsent 更直观。
HashMap<String, Integer> map = new HashMap<>();
map.put("key5", 10000);
map.computeIfAbsent("key5", k -> 2000 + 3000);
不会放入(key5, 5000)因为 key1 已经有了putIfAbsent(K key, V value)
- 场景:仅在 Key 不存在时插入,防止覆盖已有数据。
merge(K key, V value, BiFunction remappingFunction)
- 场景:计数器或合并逻辑。例如 map.merge(key, 1, Integer::sum);(如果不存在设为 1,存在则加 1)。
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}Lambda 表达式(最简洁):
- map.forEach((k, v) -> System.out.println(k + ": " + v));
仅遍历 Key 或 Value:
- map.keySet() 或 map.values()。
Notes:
if (hashMap.getOrDefault(c, 0) != 0) {
return false;
} else
hashMap.put(c, 1);
!!getOrDefault(key, defaultValue): 当Map集合中有这个key时,就使用这个key值,如果没有就使用默认值defaultValueif (!singleSet.add(board[i][j])) return false;
void putIfAbsence(path, value)
Map<String, List<String>> map = new HashMap<String, List<String>>();
Arrays.sort(strs);
for (String s : strs) {
char[] ca = s.toCharArray();
Arrays.sort(ca);
String keyStr = String.valueOf(ca);
if (!map.containsKey(keyStr)) map.put(keyStr, new ArrayList<String>());
map.get(keyStr).add(s);
}3.create array with each hash map's value:
new ArrayList<List<String>>(hashmap.values())
4.store letter in hashmap:
1. Map<Character, Integer> dictT = new HashMap<Character, Integer>();
for (int i = 0; i < t.length(); i++) {
int count = dictT.getOrDefault(t.charAt(i), 0);
dictT.put(t.charAt(i), count + 1);
}!! another possibility --> if only characters or integers, use array as the hashmap !!
2. int[] map = new int[256];
for(char c: t.toCharArray()){
map[c - 'A']++;
}- Treemap.floorEntry(int key): return a key-value mapping associated with the greatest key less than or equal to the given key, or null if there is no such key.
Treemap.ceilingEntry(int key):return a key-value mapping associated with the least key greater than or equal to the given key, or null if there is no such key.
Complexity: treemap guaranteed log(n) time cost for the containsKey, get, put and remove operations, and the implementation of floorEntry() is similar to the implementation of get() in terms of complexity.
Hashmap-problem summary https://note.youdao.com/web/#/file/WEB8268b1d897cef35a3e813ddfb5809e69/note/WEBe30238f51ab83c604d162dfa8a53492b/
| # | Title | Solution | Complexity | Note | Difficulty |
|---|---|---|---|---|---|
| 1 | 593-Valid Square | Java | do level order traversal of tree. While doing traversal, process nodes of different level separately. | easy | |
| 2 | 833-Find And Replace in String | Java | piece table, record all the "to do" changes, then put togetger the string (method 2!!! haven't finished) | medium | |
| 3 | 1-two sums | Java | O(n) | use hashmap, put what we are looking for (target sum - current) into the map | easy (hashmap!!!) |
| 4 | 12. Integer to roman | Java | O(n) | way of creating the list | Medium |
| 4 | 13. Roman to integer | Java | O(n) | consider the case of IV! | Easy |
| 5 | 30. Substring with Concatenation of All Words | Java | redo! optimize | Hard | |
| 6 | 1166. Design File System | Java | Hashmap, trie tree or graph | Medium | |
| 7 | Geek-Equilibrium index of an array | Java | Hashmap, use sum | Medium | |
| 8 | Twitter-19-OA- partitioning array | Java | Hashmap | Medium | |
| 9 | Geek-min number of manipulations to make 2 strings anagram | Java | count-sort (similar), or hashmap | Medium | |
| 10 | 299. Bulls and Cows | Java | count-sort (similar), or hashmap | Easy | |
| 11 | 350. Intersection of Two Arrays II | Java | count-sort (similar), or hashmap | Easy | |
| 12 | 169. Majority Element | Java | Moore voting, hashmap, bit, sorting | Easy | |
| 13 | interview-check variadic function type matching | Java | non-variadic function | Easy | |
| 14 | frequency Of Max Value to its right | Java | memo, store | Easy | |
| 15 | 825. Friends Of Appropriate Ages | Java | memo, store | Medium | |
| 16 | 560. number of continuous Subarray Sum Equals K | Java | similar to 2 sum, use pre-sum array in hashmap | Medium | |
| 17 | Geeks - Longest sub-array having sum k | Java | similar to 2 sum, use pre-sum array in hashmap | Medium | |
| 18 | 846. Hand of Straights --> EXACTLY length = w | Java | Treemap, exactly sequence of length w | Medium | |
| 19 | 659. Split Array into Consecutive Subsequences --> AT LEAST length = 3 | Java | 2 hashmap, AT LEAST sequence of length w | Medium | |
| 20 | 128. Longest Consecutive Sequence | Java | O(n) | hashmap | Hard |
| 21 | 809. Expressive Words | Java | O(K*n) = k words, O(n) for checking every word | hashmap, 2 pointers | Medium |
| 22 | 340. Longest Substring with At Most K Distinct Characters | Java | O(n) | hashmap, 2 pointers/sliding window | Medium |
| 23 | 981. Time Based Key-Value Store | Java | O(1) for set, O(log N) for get | hashmap + binary search, TreeMap | Medium |
| 24 | 1152. Analyze User Website Visit Pattern | Java | O(1) for set, O(log N) for get | hashmap + hashset | Medium |
| 25 | 359. Logger Rate Limiter | Java | O(n) | hashmap | Easy |
| 26 | 460. LFU Cache | Java | O(1) | 2 * hashmap + linked list | Hard |
| 27 | 835. Image Overlap | Java | reduce matrix to array by offsets, OR use padding and loop through | Medium | |
| 28 | 1146. Snapshot Array | Java | only store changed keys, binary search on TreeMap | Medium | |
| 29 | 953. Verifying an Alien Dictionary | Java | hashmap | Easy | |
| 30 | 1048. Longest String Chain | Java | hashmap | Medium | |
| 31 | 706. Design HashMap | Java | Design hashmap | Easy | |
| 32 | 811. Subdomain Visit Count | Java | use substring & hashmap | Easy | |
| 33 | 819. Most Common Word | Java | Easy | ||
| 34 | 387. First Unique Character in a String | Java | Easy | ||
| 35 | 898. Bitwise ORs of Subarrays | Java | use 3 hashmaps, result & current & prev | Medium | |
| 36 | 929. Unique Email Addresses | Java | Easy | ||
| 37 | 804. Unique Morse Code Words | Java | Easy | ||
| 38 | 982. Triples with Bitwise AND Equal To Zero | Java | DP or Hashmap | Hard | |
| 39 | 609. Find Duplicate File in System | Java | hashmap | Medium | |
| 40 | 523. Continuous Subarray Sum | Java | hashmap | Medium | |
| 41 | 697. Degree of an Array | Java | hashmap | Easy | |
| 42 | 1218. Longest Arithmetic Subsequence of Given Difference | Java | hashmap | Medium | |
| 43 | 1002. Find Common Characters | Java | hashmap | Easy | |
| 44 | 635. Design Log Storage System | Java | tree map | Medium | |
| 45 | 890. Find and Replace Pattern | Java | 2 hashmap to create bijection | Medium |
| # | Title | Solution | Complexity | Note | Difficulty |
|---|---|---|---|---|---|
| 1 | 8. String to Integer (atoi) | Java | str = "", " ", and " " | Medium | |
| 2 | 11. Container With Most water | Java | reduce calculations, 2 pointer | Medium | |
| 3 | 14. Longest Common prefix --- Easy | Java | sort or trick | Easy | |
| 4 | 18. 4 Sum | Java | increase speed --> put checks! | Medium | |
| 5 | 26. Remove Duplicates from Sorted Array | Java | method 2 -- use loop variant | Easy | |
| 6 | 29. Divide Two Integers | Java | redo!! bit manipulation boost the speed | Medium | |
| 7 | 41. First Missing Positive | Java | space need to be o(1) | Hard | |
| 8 | 42. Trapping Rain Water | Java | time:O(n), space:O(1) | 2 pointers, dp, stack | Hard |
| 9 | 43. Multiply Strings | Java | use array to count offsets | Medium | |
| 10 | 45. Jump Game II | Java | time-O(n), space-O(1) | greedy algo & how to count steps, use boundry | Hard |
| 11 | 48. Rotate Image | Java | time-O(n), space-O(1) | trick, remember how to rotate | Medium |
| 12 | 50. Pow(x, n) | Java | time-log(n), space-O(1) | many edge case, recursion | Medium |
| 13 | 58. Length of Last Word | Java | check end case | Easy | |
| 14 | 65. Valid Number | Java | check all conditions, or use FSM | Hard | |
| 15 | 153. Find Minimum in Rotated Sorted Array | Java | binary search | Medium | |
| 16 | 348. Design Tic-Tac-Toe | Java | simply check all winner condition | Medium |
| # | Title | Solution | Complexity | Note | Difficulty |
|---|---|---|---|---|---|
| 1 | 146. LRU Cache | Java | use hashmap + double linked list | Medium | |
| 2 | Trip advisor-design blackjack | Java | several classes, use enum | Medium | |
| 3 | 1114. Print in Order | Java | concurrency | Easy | |
| 4 | 588. Design In-Memory File System | Java | REDO! hashmap, very nice OOD structure | Hard |
-
length: string.length();
-
substring: string.substring(int startIndex, int endIndex) --> 不包含endindex,只到endIndex - 1 string.substring(int index): 保留这个index及其之后的所有letter ex. "abcde".substring(2) = "cde"
-
find the index within this string of the first occurrence of the specified character or -1, if the character does not occur.
string.indexOf(String sub)
-
str.indexOf(char ch, int strt ): returns the index within this string of the first occurrence of the specified character, starting the search at the specified index or -1, if the character does not occur.
str.indexOf(String str, int strt) : This method returns the index within this string of the first occurrence of the specified substring, starting at the specified index. If it does not occur, -1 is returned.
str.indexOf(String str)
-
instead of using +: s.concat(String b)
-
split: String[] arrOfStr = str.split(":");
-
change from char[] to string
// Method 1: Using String object char[] ch = {'g', 'o', 'o', 'd', ' ', 'm', 'o', 'r', 'n', 'i', 'n', 'g'}; String str = new String(ch);
// Method 2: Using valueOf method String str2 = String.valueOf(ch);
-
regex:
string.split("\(") --> \ means 'abc((((d' --> [abc,d] string.split("\.")
-
remove all special character:
String text = "This - text ! has \ /allot # of % special % characters"; text = text.replaceAll("[^a-zA-Z0-9]", ""); System.out.println(text);
String html = "This is bold"; html = html.replaceAll("[^a-zA-Z0-9\\s+]", ""); System.out.println(html);
Output Thistexthasallotofspecialcharacters b This is bold b
- Palindrome
-
-
check if palindrome:
String rev = new StringBuffer(actual).reverse().toString(); return actual.equals(rev);
-
-
- create a palindrome given the first half (lc 564) ex. orig = 12345, wants its closest palindrome --> left = 123 (depend on length of orig is even or odd), then call getPalindrome(123, len(12345)%2 == 0)
private long getPalindrome(long left, boolean even) {
long res = left;
// 123 --> 12, so only add '21' to left = 12321
if (!even)
left = left / 10;
while (left > 0) {
res = res * 10 + left % 10;
left /= 10;
}
return res;
}-
KMP algo: leetcode 214
-
check if the char is a letter: if (Character.isLetter(S.charAt(i)))
-
reverse a string:
-
reverse & string builder
String input = "Geeks for Geeks"; StringBuilder input1 = new StringBuilder(); input1.append(input); output = input1.reverse(); -
swap in string array
String input = "Geeks For Geeks"; char[] arr = input.toCharArray(); int left = 0, right= arr.length-1; for (left=0; left < right ; left++ ,right--) { // Swap values of left and right char temp = arr[left]; arr[left] = arr[right]; arr[right]=temp; }
-
From string to integer:
Integer.parseInt(str.substring(0,2) --> ex. str = 11:25, and get the integer 11
| # | Title | Solution | Complexity | Note | Difficulty |
|---|---|---|---|---|---|
| 1 | geeksforgeeks-longest non palindrome string | Java | O(4^n) | redo! tricky | Medium |
| 2 | 214. Shortest Palindrome | Java | KMP algo, redo | Hard | |
| 3 | 131. Palindrome Partitioning | Java | back-tracking, or dp | Medium | |
| 4 | 1147. Longest Chunked Palindrome Decomposition | Java | Hard | ||
| 5 | 5.Longest Palindromic Substring | Java | O(n), O(1) | !!! start from middle, 2 pointers / Manchester's algo --> linear time | Medium |
| 6 | Google - 2 string, make cut to make palindrome a1+b2 or a2+b1 | Java | O(n) | sliding window, follow up: cut can be in differnet position for str1 and str2 | Medium |
| 7 | 680. Valid Palindrome II | Java | two pointers | Easy | |
| 8 | 234. Palindrome Linked List | Java | resursion | Easy | |
| 9 | 131. Palindrome Partitioning | Java | back-tracking, or dp | Medium | |
| 10 | 516. Longest Palindromic Subsequence | Java | start from end of the string! | Medium | |
| 11 | 647. Palindromic Substrings | Java | DP | Medium | |
| 12 | 730. Count Different Palindromic Subsequences | Java | Redo, DP | Hard | |
| 13 | 1278. Palindrome Partitioning III | Java | DP, good problem | Hard | |
| 14 | 1246. Palindrome Removal | Java | DP, 3 cases | Hard | |
| 15 | 336. Palindrome Pairs | Java | Trie, not finished for method 2 and 3 | Hard | |
| 16 | Geeks- Number of palindromic paths in a matrix | Java | dfs, memo | Medium | |
| 17 | 9. Palindrome Number | Java | tricky special case, consider # end with 0, consider loop condition & comparison | Easy | |
| 18 | 866. Prime Palindrome | Java | check odd length palindrome (even length is a multiple of 11) | Medium | |
| 19 | [564. Find the Closest Palindrome]https://leetcode.com/problems/find-the-closest-palindrome/) | Java | math, corner case | Hard |
(刷tag 到 1221)
notes on minimax: notes/minimax.md
| # | Title | Solution | Complexity | Note | Difficulty |
|---|---|---|---|---|---|
| 1 | 292. Nim Game | Java | minimax, brain teaser | Easy | |
| 2 | 375. Guess Number Higher or Lower II | Java | minimax + binary search | Medium | |
| 3 | 375. Guess Number Higher or Lower II | Java | minimax + binary search | Medium | |
| 4 | 877. Stone Game | Java | minimax, dp | Medium | |
| 5 | 486. Predict the Winner | Java | !!! redo, minimax, dp | Medium | |
| 6 | 843. Guess the Word | Java | minimax, filter | Hard |
| # | Title | Solution | Complexity | Note | Difficulty |
|---|---|---|---|---|---|
| 1 | 17. Letter Combinations of a Phone Number) | Java | O(4^n) | redo! tricky | Medium |
| 2 | 20. Valid Parentheses | Java | O(4^n) | great solution 2, use array as a stack! | Easy |
| 3 | 24. Swap Nodes in Pairs | Java | redo! node swapping | Medium | |
| 4 | 25. Reverse Nodes in k-Group | Java | redo! iterative method redo | Hard | |
| 5 | 27. Remove Element | Java | redo! iterative method redo | Easy | |
| 6 | 28. Implement strStr() | Java | Easy | ||
| 7 | 36. Valid Sudoku | Java | Medium | ||
| 8 | 37. Sudoku Solver | Java | Hard | ||
| 9 | 38. Count and Say | Java | Easy | ||
| 10 | 39. Combination Sum | Java | back-tracking/dp | Medium | |
| 11 | 78. Subsets | Java | back-tracking/bit | Medium | |
| 12 | 90. Subsets II | Java | back-tracking/bit | Medium | |
| 13 | 46. Permutations | Java | !! back-tracking | Medium | |
| 14 | 47. Permutations II | Java | back-tracking | Medium | |
| 15 | 40. Combination Sum II | Java | back-tracking | Medium | |
| 16 | 131. Palindrome Partitioning | Java | back-tracking, or dp | Medium | |
| 17 | 292. Nim Game | Java | minimax, brain teaser | Easy | |
| 18 | 45. Jump Game II | Java | time-O(n), space-O(1) | greedy algo | Hard |
| 19 | 49. Group Anagrams | Java | time-O(n), space-O(1) | Medium | |
| 20 | 51. N-Queens | Java | backtrack! | Hard | |
| 21 | 53. Maximum Subarray | Java | dp & trick! (折半) | Easy | |
| 22 | 52. N-Queens II | Java | back track, set | Hard | |
| 23 | 54. Spiral Matrix | Java | find pattern | Medium | |
| 24 | 55. Jump Game | Java | similar to #45 | Medium | |
| 25 | 56. Merge Intervals | Java | similar to 57,252, 253, 435 | Medium | |
| 26 | 57. Insert Interval | Java | similar to 56, 252, 253, 435 | Hard | |
| 27 | 252. Meeting Rooms | Java | similar to 56, 252, 253, 435 | Easy | |
| 28 | 253. Meeting Rooms II | Java | similar to 56, 252, 253, 435. !!! redo | Medium | |
| 29 | 435. Non-overlapping Intervals | Java | similar to 56, 252, 253, 435. | Medium | |
| 30 | 59. Spiral Matrix II | Java | follow pattern, be careful with boundries | Medium | |
| 31 | 66. Plus One | Java | follow pattern, be careful with boundries | Medium | |
| 32 | 67. Add Binary | Java | follow pattern, be careful with boundries | Medium | |
| 33 | 68. Text Justification | Java | redo! | Hard | |
| 34 | 591. Tag Validator | Java | stack or regex | Hard | |
| 35 | Airbnb-oa4 | [Java](problems/lcairbnb-deplomacy game.java) | use hashmap | Hard | |
| 36 | 242. Valid Anagram | Java | use count or hashmap | Easy | |
| 37 | Airbnb-guess-num (cows and bulls) | Java | connect to server | Easy | |
| 38 | GS-OA-rotate-strings | Java | rotate a string to right or left | Easy | |
| 39 | 796. Rotate String | Java | use count or hashmap | Easy | |
| 40 | 463. Island Perimeter | Java | pattern of adding neighbors, math | easy | |
| 41 | 163. Missing Ranges | Java | Medium | ||
| 42 | 855. Exam Room | Java | priority queue, list, or treemap | Medium | |
| 43 | Google - compare strings (intern oa) | Java | Easy | ||
| 44 | Google-largest subarray length k | Java | Easy | ||
| 45 | Google-max time | Java | Easy | ||
| 46 | Google - Most Booked Hotel Room | Java | Easy | ||
| 47 | 227. Basic Calculator II | Java | stack, or use while | Medium | |
| 48 | 224. Basic Calculator | Java | stack, or use while | Hard | |
| 49 | Geeks - Next Greater Element (in the array) | Java | stack: pop if smaller than current, assign value | medium | |
| 50 | 155. Min Stack | Java | stack store [cur_value, min_value] or 2 stack | Easy | |
| 51 | 843. Guess the Word | Java | minimax, filter | Hard | |
| 52 | 1170. Compare Strings by Frequency of the Smallest Character | Java | count array or binary search | Easy | |
| 53 | 679. 24 Game | Java | backtrack | Hard | |
| 54 | 79. Word Search | Java | 5acktrack | Medium | |
| 55 | 93. Restore IP Addresses | Java | backtrack | Medium | |
| 56 | 946. Validate Stack Sequences | Java | O(n), space O(n) --> O(1) | stimulation | Medium |
| 57 | 89. Gray Code | Java | bits + find pattern + backtrack | Medium | |
| 58 | 357. Count Numbers with Unique Digits | Java | backtrack OR combinatory | Medium | |
| 59 | 243. Shortest Word Distance | Java | Easy | ||
| 60 | 73. Set Matrix Zeroes | Java | Medium | ||
| 61 | 306. Additive Number | Java | interesting & tricky, find length of first & 2nd number before checking for validity --> early fail | Medium | |
| 62 | 401. Binary Watch | Java | backtrack | Easy | |
| 63 | 216. Combination Sum III | Java | backtrack | Medium | |
| 64 | 351. Android Unlock Patterns | Java | backtrack OR DFS | Medium | |
| 65 | 320. Generalized Abbreviation | Java | backtrack | Medium | |
| 66 | 1079. Letter Tile Possibilities | Java | backtrack | Medium | |
| 67 | 526. Beautiful Arrangement | Java | backtrack | Medium | |
| 68 | 784. Letter Case Permutation | Java | backtrack/BFS/ DFS | Easy | |
| 69 | 1240. Tiling a Rectangle with the Fewest Squares | Java | backtrack/BFS/ DFS | Hard | |
| 70 | 303. Range Sum Query - Immutable | Java | prefix sum array | Easy | |
| 71 | 87. Scramble String | Java | recursion | Hard | |
| 72 | 698. Partition to K Equal Sum Subsets | Java | backtrack | Medium | |
| 73 | 202. Happy Number | Java | detect cycle with slow & fast rabbit | Easy | |
| 74 | 638. Shopping Offers | Java | backtrack | Medium | |
| 75 | 412. Fizz Buzz | Java | bruteforce or hashmap | Easy | |
| 76 | 935. Knight Dialer | Java | backtrack / dfs + memo | Medium | |
| 77 | 204. Count Primes | Java | Easy | ||
| 78 | 561. Array Partition I | Java | Easy | ||
| 79 | 944. Delete Columns to Make Sorted | Java | Easy | ||
| 80 | 289. Game of Life | Java | use 4 variables to denote this state & next state, then update entire board by %2 | Medium | |
| 81 | 442. Find All Duplicates in an Array | Java | similar to lc 41. , keep swapping to its correct position | Medium | |
| 82 | 448. Find All Numbers Disappeared in an Array | Java | similar to lc 41. , keep swapping to its correct position | Easy | |
| 83 | 657. Robot Return to Origin | Java | Easy | ||
| 84 | 1147. Longest Chunked Palindrome Decomposition | Java | Hard | ||
| 84 | 999. Available Captures for Rook | Java | Easy |
315 count of smaller numbers after self -- merge sort, binary indexed tree 552 student attendance record 2 -- DP, 重新推导 42 trapping rain water 44 the dp solution 121 Best Time to Buy and Sell Stock 85 Max rectangle -- DP, how to 'compress' the 2D matrix 140 word break 2 -- dfs & backtrack, find pattern 1240 tiling a rectangle with fewest squares -- backtrack 1130 min cost tree from leaf values -- understand the problem.... + stack 309 All the stock buy & sell problems -- https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/discuss/108870/Most-consistent-ways-of-dealing-with-the-series-of-stock-problems 403 Frog jump -- very cool DP optimization: use array to store reachable jumps 706 Design Hashmap 494 target sum -- weird DP 903 valid permutations of DI seqeunce -- hard to think of dp 1000 Min cost to merge stones -- similar to burst ballons/matrix multiplication, but a little twist good dp practise problem 733 flood fill -- good practise problem, DFS, BFS 361 bomb-enemy -- interesting way to store & DP 292 Nin Game 960 delete to make column sorted 3 41 first missing positive --> template use for many other find xxx in array[1~n] 691 stickers to spell word --> good string / decompose / backtrack problem 1235 Maximum Profit in Job Scheduling --> classic problem, use TreeMap or sort + binary search for floor entry 609 find duplicate file in system --> good follow up problems! 1125 smallest sufficient team --> set cover DP problem 214 shortest palindrome --> KMP algorithm 514 Freedom Trail --> good DP problem 1349 maximum students taking exam --> DP + bit mask
在腾讯doc里面
| # | Title | Solution | Complexity | Note | Difficulty |
|---|---|---|---|---|---|
| 1 | 182. Duplicate Emails) | Java | having, self-join | Easy |
- always start with empty or null pointer
- check corner cases
- with int, consider have leading 0's
- string.charAt(position)
- faster run time --> puts more checks before heading to the for loop + break quick if sth. went wrong
- trick: //decrease list size to half --> len = (len+1)/2;
- find unique xxx --> if given a list/array, first sort the array, then use if (nums[i] == nums[i-1]) continue; in a for loop gto avoid
- sometimes let the false condition to return false maybe easier
1130 Minimum Cost Tree From Leaf Values 907 Sum of Subarray Minimums 901 Online Stock Span 856 Score of Parentheses 503 Next Greater Element II 496 Next Greater Element I 84 Largest Rectangle in Histogram 42 Trapping Rain Water
| # | Title | Match Question | Note |
|---|---|---|---|
| 1 | backtracking) | 78. Subsets, 46.permutation, 47. permutation II, 51. N-Queens | recursion |