|
| 1 | +🗓️ 06072026 1200 |
| 2 | + |
| 3 | +# leetcode_java_cheatsheet |
| 4 | + |
| 5 | +**What it is:** |
| 6 | +- Syntax reference for the data structures used most often in LeetCode-style problems, in Java |
| 7 | +- Focused on the operations that come up under time pressure — construction, common methods, iteration, gotchas |
| 8 | +- Not a DSA concepts primer — assumes you know what a heap/deque/trie *is*, just not the Java spelling of it |
| 9 | + |
| 10 | +## Arrays |
| 11 | + |
| 12 | +```java |
| 13 | +int[] arr = new int[10]; // fixed size, zero-initialized |
| 14 | +int[] arr = {1, 2, 3}; // literal |
| 15 | +int[][] grid = new int[rows][cols]; // 2D, zero-initialized |
| 16 | +int[][] grid = {{1, 2}, {3, 4}}; // 2D literal |
| 17 | + |
| 18 | +Arrays.fill(arr, -1); // fill all |
| 19 | +Arrays.sort(arr); // ascending, in place |
| 20 | +Arrays.sort(arr, from, to); // sort sub-range [from, to) |
| 21 | +int[] copy = Arrays.copyOf(arr, arr.length); |
| 22 | +int[] slice = Arrays.copyOfRange(arr, from, to); // [from, to) |
| 23 | +Arrays.equals(a, b); // element-wise equality |
| 24 | +String s = Arrays.toString(arr); // "[1, 2, 3]" for debugging |
| 25 | + |
| 26 | +// Sort descending (Integer[] only — primitives have no Comparator overload) |
| 27 | +Integer[] boxed = {3, 1, 2}; |
| 28 | +Arrays.sort(boxed, Collections.reverseOrder()); |
| 29 | + |
| 30 | +// Sort 2D array by a column |
| 31 | +Arrays.sort(grid, (a, b) -> a[0] - b[0]); // by col 0 ascending |
| 32 | +Arrays.sort(grid, (a, b) -> b[0] - a[0]); // by col 0 descending |
| 33 | +``` |
| 34 | + |
| 35 | +```ad-warning |
| 36 | +`Arrays.sort` on `int[]` uses dual-pivot quicksort (O(n log n) avg, O(n²) worst). On `Object[]` (including `Integer[]`) it uses TimSort — stable, guaranteed O(n log n). Prefer `Integer[]` when a stable sort or custom comparator matters. |
| 37 | +``` |
| 38 | + |
| 39 | +## ArrayList |
| 40 | + |
| 41 | +```java |
| 42 | +List<Integer> list = new ArrayList<>(); |
| 43 | +list.add(5); // append |
| 44 | +list.add(0, 5); // insert at index — O(n) |
| 45 | +list.get(i); |
| 46 | +list.set(i, val); // overwrite |
| 47 | +list.remove(i); // remove by INDEX — O(n) |
| 48 | +list.remove(Integer.valueOf(5)); // remove by VALUE (autobox to disambiguate) |
| 49 | +list.contains(5); // O(n) |
| 50 | +list.indexOf(5); // O(n), -1 if absent |
| 51 | +list.size(); |
| 52 | +list.isEmpty(); |
| 53 | +Collections.sort(list); |
| 54 | +Collections.reverse(list); |
| 55 | +Collections.max(list); |
| 56 | +Collections.min(list); |
| 57 | + |
| 58 | +// int[] <-> List<Integer> conversions (no direct cast) |
| 59 | +List<Integer> fromArr = Arrays.stream(arr).boxed().collect(Collectors.toList()); |
| 60 | +int[] toArr = list.stream().mapToInt(Integer::intValue).toArray(); |
| 61 | +``` |
| 62 | + |
| 63 | +```ad-warning |
| 64 | +`list.remove(5)` removes the element **at index 5**. `list.remove(Integer.valueOf(5))` removes the value **5**. This is a classic LeetCode footgun with `int` lists. |
| 65 | +``` |
| 66 | + |
| 67 | +## HashMap / HashSet |
| 68 | + |
| 69 | +```java |
| 70 | +Map<String, Integer> map = new HashMap<>(); |
| 71 | +map.put("a", 1); |
| 72 | +map.get("a"); // null if absent |
| 73 | +map.getOrDefault("a", 0); |
| 74 | +map.containsKey("a"); |
| 75 | +map.remove("a"); |
| 76 | +map.put("a", map.getOrDefault("a", 0) + 1); // classic counting bump |
| 77 | +map.merge("a", 1, Integer::sum); // same, one line |
| 78 | +map.computeIfAbsent(key, k -> new ArrayList<>()).add(val); // group-by / adjacency list build |
| 79 | + |
| 80 | +for (Map.Entry<String, Integer> e : map.entrySet()) { e.getKey(); e.getValue(); } |
| 81 | +for (String k : map.keySet()) { } |
| 82 | +for (int v : map.values()) { } |
| 83 | + |
| 84 | +Set<Integer> set = new HashSet<>(); |
| 85 | +set.add(1); |
| 86 | +set.contains(1); |
| 87 | +set.remove(1); |
| 88 | + |
| 89 | +Set<Integer> set = new HashSet<>(list); // dedupe a list in one line |
| 90 | +``` |
| 91 | + |
| 92 | +```ad-info |
| 93 | +`LinkedHashMap` / `LinkedHashSet` preserve insertion order — use when iteration order matters (e.g. building an LRU cache). `TreeMap` / `TreeSet` keep keys sorted, backed by a red-black tree, O(log n) ops — use when you need order + range queries instead of a heap. |
| 94 | +``` |
| 95 | + |
| 96 | +## Deque (stack, queue, and monotonic deque) |
| 97 | + |
| 98 | +`ArrayDeque` is the go-to — faster than `Stack`/`LinkedList` and not synchronized. |
| 99 | + |
| 100 | +```java |
| 101 | +Deque<Integer> stack = new ArrayDeque<>(); |
| 102 | +stack.push(1); // add to head |
| 103 | +stack.pop(); // remove from head, throws if empty |
| 104 | +stack.peek(); // read head, null if empty |
| 105 | + |
| 106 | +Deque<Integer> queue = new ArrayDeque<>(); |
| 107 | +queue.offer(1); // add to tail |
| 108 | +queue.poll(); // remove from head, null if empty |
| 109 | +queue.peek(); // read head, null if empty |
| 110 | + |
| 111 | +// Monotonic deque (sliding window max, etc.) — needs both ends |
| 112 | +deque.offerFirst(x); deque.offerLast(x); |
| 113 | +deque.pollFirst(); deque.pollLast(); |
| 114 | +deque.peekFirst(); deque.peekLast(); |
| 115 | +``` |
| 116 | + |
| 117 | +```ad-warning |
| 118 | +`pop()`/`push()` on `ArrayDeque` operate on the **head** — so `ArrayDeque` as a stack pushes/pops from the same end you'd `poll()` from as a queue. Don't mix stack and queue method names on the same instance; pick `offer`/`poll` (queue) or `push`/`pop` (stack) and stay consistent. |
| 119 | +``` |
| 120 | + |
| 121 | +## PriorityQueue (heap) |
| 122 | + |
| 123 | +```java |
| 124 | +PriorityQueue<Integer> minHeap = new PriorityQueue<>(); // min-heap by default |
| 125 | +PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder()); |
| 126 | +PriorityQueue<int[]> byFirst = new PriorityQueue<>((a, b) -> a[0] - b[0]); |
| 127 | + |
| 128 | +heap.offer(5); // add |
| 129 | +heap.poll(); // remove + return min/max, null if empty |
| 130 | +heap.peek(); // read min/max, null if empty |
| 131 | +heap.size(); |
| 132 | + |
| 133 | +// Heapify an existing collection in O(n) instead of n offers (O(n log n)) |
| 134 | +PriorityQueue<Integer> heap = new PriorityQueue<>(list); |
| 135 | +``` |
| 136 | + |
| 137 | +```ad-warning |
| 138 | +`(a, b) -> a[0] - b[0]` overflows if values approach `Integer.MIN_VALUE`/`MAX_VALUE`. Use `Integer.compare(a[0], b[0])` when magnitudes are unbounded. |
| 139 | +``` |
| 140 | + |
| 141 | +## StringBuilder |
| 142 | + |
| 143 | +```java |
| 144 | +StringBuilder sb = new StringBuilder(); |
| 145 | +sb.append("x").append(5); // chainable, mixed types |
| 146 | +sb.insert(0, "y"); // prepend |
| 147 | +sb.deleteCharAt(sb.length() - 1); |
| 148 | +sb.reverse(); |
| 149 | +sb.charAt(i); |
| 150 | +sb.setCharAt(i, 'z'); |
| 151 | +sb.toString(); |
| 152 | +sb.length(); |
| 153 | +``` |
| 154 | + |
| 155 | +```ad-info |
| 156 | +Strings are immutable in Java — `str += c` in a loop is O(n) per append, O(n²) overall. Always use `StringBuilder` when building a string incrementally. |
| 157 | +``` |
| 158 | + |
| 159 | +## String |
| 160 | + |
| 161 | +```java |
| 162 | +s.charAt(i); |
| 163 | +s.length(); |
| 164 | +s.substring(from); // [from, end) |
| 165 | +s.substring(from, to); // [from, to) |
| 166 | +s.split(","); // regex-based — escape special chars: split("\\.") |
| 167 | +s.toCharArray(); |
| 168 | +String.valueOf(charArray); |
| 169 | +s.equals(other); // NEVER use == for content comparison |
| 170 | +s.compareTo(other); |
| 171 | +s.indexOf('c'); // -1 if absent |
| 172 | +String.join(",", list); |
| 173 | +s.trim(); |
| 174 | +s.toLowerCase(); s.toUpperCase(); |
| 175 | +Character.isDigit(c); Character.isLetter(c); Character.isLetterOrDigit(c); |
| 176 | +Character.toLowerCase(c); |
| 177 | +``` |
| 178 | + |
| 179 | +```ad-warning |
| 180 | +`==` compares references for `String`/boxed types, not content. Two equal-looking strings from different sources can be `==` false. Always use `.equals()`. (Integer caching makes `Integer == Integer` "work" for -128..127 only — another reason to avoid `==` on boxed types entirely.) |
| 181 | +``` |
| 182 | + |
| 183 | +## Trees & Linked Lists (typical LeetCode node defs) |
| 184 | + |
| 185 | +```java |
| 186 | +class TreeNode { |
| 187 | + int val; |
| 188 | + TreeNode left, right; |
| 189 | + TreeNode(int val) { this.val = val; } |
| 190 | +} |
| 191 | + |
| 192 | +class ListNode { |
| 193 | + int val; |
| 194 | + ListNode next; |
| 195 | + ListNode(int val) { this.val = val; } |
| 196 | +} |
| 197 | + |
| 198 | +// Dummy head pattern — avoids special-casing an empty result list |
| 199 | +ListNode dummy = new ListNode(0); |
| 200 | +ListNode curr = dummy; |
| 201 | +// ... curr.next = new ListNode(x); curr = curr.next; |
| 202 | +return dummy.next; |
| 203 | +``` |
| 204 | + |
| 205 | +## Trie |
| 206 | + |
| 207 | +```java |
| 208 | +class TrieNode { |
| 209 | + TrieNode[] children = new TrieNode[26]; |
| 210 | + boolean isWord; |
| 211 | +} |
| 212 | +// index children with c - 'a' for lowercase-letter problems |
| 213 | +``` |
| 214 | + |
| 215 | +## Union-Find (Disjoint Set Union) |
| 216 | + |
| 217 | +```java |
| 218 | +int[] parent = new int[n]; |
| 219 | +int[] rank = new int[n]; |
| 220 | +for (int i = 0; i < n; i++) parent[i] = i; |
| 221 | + |
| 222 | +int find(int x) { |
| 223 | + if (parent[x] != x) parent[x] = find(parent[x]); // path compression |
| 224 | + return parent[x]; |
| 225 | +} |
| 226 | + |
| 227 | +void union(int a, int b) { |
| 228 | + int ra = find(a), rb = find(b); |
| 229 | + if (ra == rb) return; |
| 230 | + if (rank[ra] < rank[rb]) { int t = ra; ra = rb; rb = t; } |
| 231 | + parent[rb] = ra; |
| 232 | + if (rank[ra] == rank[rb]) rank[ra]++; |
| 233 | +} |
| 234 | +``` |
| 235 | + |
| 236 | +## Sorting with Comparator (multi-key, common interval pattern) |
| 237 | + |
| 238 | +```java |
| 239 | +// int[][] intervals, sort by start then end |
| 240 | +Arrays.sort(intervals, (a, b) -> a[0] != b[0] ? a[0] - b[0] : a[1] - b[1]); |
| 241 | + |
| 242 | +// List<T> with Comparator.comparing chains |
| 243 | +list.sort(Comparator.comparing((int[] a) -> a[0]).thenComparing(a -> a[1])); |
| 244 | + |
| 245 | +// Custom object, descending |
| 246 | +people.sort((a, b) -> b.score - a.score); |
| 247 | +``` |
| 248 | + |
| 249 | +## Bit Manipulation |
| 250 | + |
| 251 | +```java |
| 252 | +x & 1 // check odd/even |
| 253 | +x >> 1 // divide by 2 |
| 254 | +x << 1 // multiply by 2 |
| 255 | +x & (x - 1) // clear lowest set bit |
| 256 | +x & (-x) // isolate lowest set bit |
| 257 | +Integer.bitCount(x) // popcount |
| 258 | +Integer.toBinaryString(x) |
| 259 | +1 << k // bit mask for position k |
| 260 | +``` |
| 261 | + |
| 262 | +## Complexity Cheat Sheet |
| 263 | + |
| 264 | +| Structure | Access | Search | Insert | Delete | |
| 265 | +|---------------------|--------|--------|--------|--------| |
| 266 | +| ArrayList | O(1) | O(n) | O(n)* | O(n) | |
| 267 | +| HashMap/HashSet | - | O(1) | O(1) | O(1) | |
| 268 | +| TreeMap/TreeSet | - | O(log n) | O(log n) | O(log n) | |
| 269 | +| ArrayDeque (as stack/queue) | O(1) ends | O(n) | O(1) ends | O(1) ends | |
| 270 | +| PriorityQueue | O(1) peek | O(n) | O(log n) | O(log n) | |
| 271 | + |
| 272 | +*O(1) amortized for append at the end; O(n) for insert/remove at arbitrary index. |
| 273 | + |
| 274 | +--- |
| 275 | + |
| 276 | +## References |
| 277 | + |
| 278 | +- https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/package-summary.html |
| 279 | +- [[java_concurrency_data_structures]] |
0 commit comments