Extras - Mixed Problems
1. Reverse String
Description:
Write a function that reverses a string. The input string is given as an array of characters.
Java Solution:
public void reverseString(char[] s) {
int left = 0, right = s.length - 1;
while (left < right) {
char temp = s[left];
s[left++] = s[right];
s[right--] = temp;
}
}
Explanation:
Use two pointers to swap characters from both ends moving toward the center.
- Time Complexity: O(n)
- Space Complexity: O(1)
2. Fizz Buzz
Description:
Given an integer n, return a string array answer where answer[i] is “FizzBuzz” if i is divisible by 3 and 5, “Fizz” if divisible by 3, “Buzz” if divisible by 5, else the number.
Java Solution:
public List<String> fizzBuzz(int n) {
List<String> result = new ArrayList<>();
for (int i = 1; i <= n; i++) {
if (i % 15 == 0) result.add("FizzBuzz");
else if (i % 3 == 0) result.add("Fizz");
else if (i % 5 == 0) result.add("Buzz");
else result.add(String.valueOf(i));
}
return result;
}
Explanation:
Check divisibility in order: 15, 3, 5.
- Time Complexity: O(n)
- Space Complexity: O(1) excluding output
3. Single Number
Description:
Given a non-empty array of integers where every element appears twice except for one, find that single one.
Java Solution:
public int singleNumber(int[] nums) {
int result = 0;
for (int num : nums) {
result ^= num;
}
return result;
}
Explanation:
XOR of two same numbers is 0. XOR of a number with 0 is the number itself.
- Time Complexity: O(n)
- Space Complexity: O(1)
4. Maximum Depth of Binary Tree
Description:
Given the root of a binary tree, return its maximum depth.
Java Solution:
public int maxDepth(TreeNode root) {
if (root == null) return 0;
return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
}
Explanation:
Recursively calculate depth of left and right subtrees.
- Time Complexity: O(n)
- Space Complexity: O(h) where h is height
5. Delete Node in a Linked List
Description:
Write a function to delete a node in a singly-linked list. You will not be given access to the head.
Java Solution:
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
Explanation:
Copy next node’s value and skip next node.
- Time Complexity: O(1)
- Space Complexity: O(1)
6. Move Zeroes
Description:
Given an integer array nums, move all 0’s to the end while maintaining relative order of non-zero elements.
Java Solution:
public void moveZeroes(int[] nums) {
int j = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != 0) {
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
j++;
}
}
}
Explanation:
Use two pointers to swap non-zero elements forward.
- Time Complexity: O(n)
- Space Complexity: O(1)
7. Sum of Two Integers
Description:
Given two integers a and b, return the sum without using + or - operators.
Java Solution:
public int getSum(int a, int b) {
while (b != 0) {
int carry = (a & b) << 1;
a = a ^ b;
b = carry;
}
return a;
}
Explanation:
Use XOR for sum without carry and AND with left shift for carry.
- Time Complexity: O(1)
- Space Complexity: O(1)
8. Excel Sheet Column Number
Description:
Given a column title as appears in an Excel sheet, return its corresponding column number.
Java Solution:
public int titleToNumber(String columnTitle) {
int result = 0;
for (char c : columnTitle.toCharArray()) {
result = result * 26 + (c - 'A' + 1);
}
return result;
}
Explanation:
Convert base-26 to decimal.
- Time Complexity: O(n)
- Space Complexity: O(1)
9. Majority Element
Description:
Given an array of size n, find the majority element appearing more than ⌊n/2⌋ times.
Java Solution:
public int majorityElement(int[] nums) {
int count = 0, candidate = 0;
for (int num : nums) {
if (count == 0) candidate = num;
count += (num == candidate) ? 1 : -1;
}
return candidate;
}
Explanation:
Boyer-Moore Voting Algorithm.
- Time Complexity: O(n)
- Space Complexity: O(1)
10. Number of 1 Bits
Description:
Write a function that takes an unsigned integer and returns the number of ‘1’ bits.
Java Solution:
public int hammingWeight(int n) {
int count = 0;
while (n != 0) {
count++;
n &= (n - 1);
}
return count;
}
Explanation:
n & (n-1) removes the rightmost 1 bit.
- Time Complexity: O(1)
- Space Complexity: O(1)
11. Palindrome Number
Description:
Determine whether an integer is a palindrome without converting it to a string.
Java Solution:
public boolean isPalindrome(int x) {
if (x < 0) return false;
int original = x, reversed = 0;
while (x > 0) {
reversed = reversed * 10 + x % 10;
x /= 10;
}
return original == reversed;
}
Explanation:
Reverse the number and compare with original.
- Time Complexity: O(log n)
- Space Complexity: O(1)
12. Roman to Integer
Description:
Convert a Roman numeral to an integer.
Java Solution:
public int romanToInt(String s) {
Map<Character, Integer> map = new HashMap<>();
map.put('I', 1); map.put('V', 5); map.put('X', 10);
map.put('L', 50); map.put('C', 100); map.put('D', 500); map.put('M', 1000);
int result = 0;
for (int i = 0; i < s.length(); i++) {
if (i < s.length() - 1 && map.get(s.charAt(i)) < map.get(s.charAt(i + 1))) {
result -= map.get(s.charAt(i));
} else {
result += map.get(s.charAt(i));
}
}
return result;
}
Explanation:
Subtract if current value is less than next, otherwise add.
- Time Complexity: O(n)
- Space Complexity: O(1)
13. Longest Common Prefix
Description:
Find the longest common prefix string amongst an array of strings.
Java Solution:
public String longestCommonPrefix(String[] strs) {
if (strs.length == 0) return "";
String prefix = strs[0];
for (int i = 1; i < strs.length; i++) {
while (strs[i].indexOf(prefix) != 0) {
prefix = prefix.substring(0, prefix.length() - 1);
if (prefix.isEmpty()) return "";
}
}
return prefix;
}
Explanation:
Compare prefix with each string and shrink as needed.
- Time Complexity: O(S) where S is sum of all characters
- Space Complexity: O(1)
14. Valid Parentheses
Description:
Determine if the input string has valid parentheses.
Java Solution:
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (c == '(') stack.push(')');
else if (c == '{') stack.push('}');
else if (c == '[') stack.push(']');
else if (stack.isEmpty() || stack.pop() != c) return false;
}
return stack.isEmpty();
}
Explanation:
Use stack to match closing brackets.
- Time Complexity: O(n)
- Space Complexity: O(n)
15. Merge Two Sorted Lists
Description:
Merge two sorted linked lists and return it as a sorted list.
Java Solution:
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
curr.next = l1;
l1 = l1.next;
} else {
curr.next = l2;
l2 = l2.next;
}
curr = curr.next;
}
curr.next = l1 != null ? l1 : l2;
return dummy.next;
}
Explanation:
Compare nodes and link smaller one.
- Time Complexity: O(n + m)
- Space Complexity: O(1)
16. Remove Duplicates from Sorted Array
Description:
Remove duplicates in-place from a sorted array.
Java Solution:
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int j = 0;
for (int i = 1; i < nums.length; i++) {
if (nums[i] != nums[j]) {
nums[++j] = nums[i];
}
}
return j + 1;
}
Explanation:
Use two pointers to track unique elements.
- Time Complexity: O(n)
- Space Complexity: O(1)
17. Implement strStr()
Description:
Return the index of the first occurrence of needle in haystack, or -1.
Java Solution:
public int strStr(String haystack, String needle) {
if (needle.isEmpty()) return 0;
for (int i = 0; i <= haystack.length() - needle.length(); i++) {
if (haystack.substring(i, i + needle.length()).equals(needle)) {
return i;
}
}
return -1;
}
Explanation:
Check each position for substring match.
- Time Complexity: O(n*m)
- Space Complexity: O(1)
18. Search Insert Position
Description:
Find the index where target would be inserted in a sorted array.
Java Solution:
public int searchInsert(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) left = mid + 1;
else right = mid - 1;
}
return left;
}
Explanation:
Binary search to find insertion position.
- Time Complexity: O(log n)
- Space Complexity: O(1)
19. Maximum Subarray
Description:
Find the contiguous subarray with the largest sum.
Java Solution:
public int maxSubArray(int[] nums) {
int maxSum = nums[0], currSum = nums[0];
for (int i = 1; i < nums.length; i++) {
currSum = Math.max(nums[i], currSum + nums[i]);
maxSum = Math.max(maxSum, currSum);
}
return maxSum;
}
Explanation:
Kadane’s algorithm.
- Time Complexity: O(n)
- Space Complexity: O(1)
20. Length of Last Word
Description:
Return the length of the last word in a string.
Java Solution:
public int lengthOfLastWord(String s) {
s = s.trim();
int length = 0;
for (int i = s.length() - 1; i >= 0; i--) {
if (s.charAt(i) != ' ') length++;
else if (length > 0) break;
}
return length;
}
Explanation:
Traverse from end until space after word found.
- Time Complexity: O(n)
- Space Complexity: O(1)
21. Merge Two Sorted Lists
Description: You are given the heads of two sorted linked lists list1 and list2. Merge the two lists into one sorted list by splicing together the nodes of the two lists. Return the head of the merged linked list.
Java Solution:
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode dummy = new ListNode(0);
ListNode current = dummy;
while (list1 != null && list2 != null) {
if (list1.val <= list2.val) {
current.next = list1;
list1 = list1.next;
} else {
current.next = list2;
list2 = list2.next;
}
current = current.next;
}
current.next = (list1 != null) ? list1 : list2;
return dummy.next;
}
Explanation: Uses a dummy node and iteratively compares values from both lists, linking the smaller node to the result list. After one list is exhausted, append the remaining nodes from the other list.
- Time Complexity: O(n + m) where n and m are lengths of the lists
- Space Complexity: O(1)
22. Generate Parentheses
Description: Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
Java Solution:
public List<String> generateParenthesis(int n) {
List<String> result = new ArrayList<>();
backtrack(result, "", 0, 0, n);
return result;
}
private void backtrack(List<String> result, String current, int open, int close, int max) {
if (current.length() == max * 2) {
result.add(current);
return;
}
if (open < max) {
backtrack(result, current + "(", open + 1, close, max);
}
if (close < open) {
backtrack(result, current + ")", open, close + 1, max);
}
}
Explanation: Uses backtracking to generate valid parentheses combinations. Only add ’(’ if count is less than n, and only add ’)’ if it doesn’t exceed open parentheses count.
- Time Complexity: O(4^n / √n) - Catalan number
- Space Complexity: O(n) for recursion depth
23. Merge k Sorted Lists
Description: You are given an array of k linked-lists lists, each linked-list is sorted in ascending order. Merge all the linked-lists into one sorted linked-list and return it.
Java Solution:
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) return null;
PriorityQueue<ListNode> pq = new PriorityQueue<>((a, b) -> a.val - b.val);
for (ListNode node : lists) {
if (node != null) pq.offer(node);
}
ListNode dummy = new ListNode(0);
ListNode current = dummy;
while (!pq.isEmpty()) {
ListNode node = pq.poll();
current.next = node;
current = current.next;
if (node.next != null) pq.offer(node.next);
}
return dummy.next;
}
Explanation: Uses a min-heap (PriorityQueue) to efficiently get the smallest node among all k lists. Add all list heads to the heap, poll the minimum, add it to result, and add the next node from that list.
- Time Complexity: O(N log k) where N is total nodes and k is number of lists
- Space Complexity: O(k) for the heap
24. Swap Nodes in Pairs
Description: Given a linked list, swap every two adjacent nodes and return its head. You must solve the problem without modifying the values in the list’s nodes (i.e., only nodes themselves may be changed).
Java Solution:
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null) return head;
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode prev = dummy;
while (prev.next != null && prev.next.next != null) {
ListNode first = prev.next;
ListNode second = prev.next.next;
first.next = second.next;
second.next = first;
prev.next = second;
prev = first;
}
return dummy.next;
}
Explanation: Uses a dummy node and iteratively swaps pairs. For each pair, rearrange pointers to swap the nodes, then move to the next pair.
- Time Complexity: O(n)
- Space Complexity: O(1)
25. Reverse Nodes in k-Group
Description: Given the head of a linked list, reverse the nodes of the list k at a time, and return the modified list. If the number of nodes is not a multiple of k, left-out nodes should remain as they are.
Java Solution:
public ListNode reverseKGroup(ListNode head, int k) {
if (head == null || k == 1) return head;
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode prev = dummy;
while (true) {
ListNode kth = getKth(prev, k);
if (kth == null) break;
ListNode groupNext = kth.next;
ListNode groupPrev = prev.next;
ListNode curr = prev.next;
while (curr != groupNext) {
ListNode temp = curr.next;
curr.next = groupNext;
groupNext = curr;
curr = temp;
}
prev.next = kth;
prev = groupPrev;
}
return dummy.next;
}
private ListNode getKth(ListNode curr, int k) {
while (curr != null && k > 0) {
curr = curr.next;
k--;
}
return curr;
}
Explanation: Find groups of k nodes, reverse each group using pointer manipulation, and connect them. Skip incomplete groups at the end.
- Time Complexity: O(n)
- Space Complexity: O(1)
26. Remove Duplicates from Sorted Array
Description: Given an integer array nums sorted in non-decreasing order, remove the duplicates in-place such that each unique element appears only once. Return the number of unique elements in nums.
Java Solution:
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int writeIndex = 1;
for (int i = 1; i < nums.length; i++) {
if (nums[i] != nums[i - 1]) {
nums[writeIndex] = nums[i];
writeIndex++;
}
}
return writeIndex;
}
Explanation: Uses two pointers: one for reading and one for writing unique elements. When a new unique element is found, write it to the write position.
- Time Complexity: O(n)
- Space Complexity: O(1)
27. Remove Element
Description: Given an integer array nums and an integer val, remove all occurrences of val in nums in-place. Return the number of elements in nums which are not equal to val.
Java Solution:
public int removeElement(int[] nums, int val) {
int writeIndex = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != val) {
nums[writeIndex] = nums[i];
writeIndex++;
}
}
return writeIndex;
}
Explanation: Uses two pointers to overwrite elements equal to val. The write pointer tracks where to place the next non-val element.
- Time Complexity: O(n)
- Space Complexity: O(1)
28. Find the Index of the First Occurrence in a String
Description: Given two strings needle and haystack, return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
Java Solution:
public int strStr(String haystack, String needle) {
if (needle.length() == 0) return 0;
if (haystack.length() < needle.length()) return -1;
for (int i = 0; i <= haystack.length() - needle.length(); i++) {
int j = 0;
while (j < needle.length() && haystack.charAt(i + j) == needle.charAt(j)) {
j++;
}
if (j == needle.length()) return i;
}
return -1;
}
Explanation: Slides a window of size needle.length() across haystack and checks for a match at each position.
- Time Complexity: O(n * m) where n is haystack length and m is needle length
- Space Complexity: O(1)
29. Divide Two Integers
Description: Given two integers dividend and divisor, divide two integers without using multiplication, division, and mod operator. Return the quotient after dividing dividend by divisor.
Java Solution:
public int divide(int dividend, int divisor) {
if (dividend == Integer.MIN_VALUE && divisor == -1) return Integer.MAX_VALUE;
boolean negative = (dividend < 0) ^ (divisor < 0);
long ldividend = Math.abs((long) dividend);
long ldivisor = Math.abs((long) divisor);
int result = 0;
while (ldividend >= ldivisor) {
long temp = ldivisor;
int count = 1;
while (temp << 1 <= ldividend) {
temp <<= 1;
count <<= 1;
}
ldividend -= temp;
result += count;
}
return negative ? -result : result;
}
Explanation: Uses bit shifting to repeatedly subtract the largest possible multiple of divisor from dividend. Doubles the divisor using left shift until it exceeds the remaining dividend.
- Time Complexity: O(log n)
- Space Complexity: O(1)
30. Substring with Concatenation of All Words
Description: You are given a string s and an array of strings words. All the strings of words are of the same length. Return all starting indices of substring(s) in s that is a concatenation of each word in words exactly once.
Java Solution:
public List<Integer> findSubstring(String s, String[] words) {
List<Integer> result = new ArrayList<>();
if (s == null || words == null || words.length == 0) return result;
int wordLen = words[0].length();
int wordCount = words.length;
int totalLen = wordLen * wordCount;
Map<String, Integer> wordMap = new HashMap<>();
for (String word : words) {
wordMap.put(word, wordMap.getOrDefault(word, 0) + 1);
}
for (int i = 0; i <= s.length() - totalLen; i++) {
Map<String, Integer> seen = new HashMap<>();
int j = 0;
while (j < wordCount) {
int wordStart = i + j * wordLen;
String word = s.substring(wordStart, wordStart + wordLen);
if (!wordMap.containsKey(word)) break;
seen.put(word, seen.getOrDefault(word, 0) + 1);
if (seen.get(word) > wordMap.get(word)) break;
j++;
}
if (j == wordCount) result.add(i);
}
return result;
}
Explanation: Uses sliding window with hash maps to track word frequencies. For each position, check if the next concatenation matches all words.
- Time Complexity: O(n * m * k) where n is string length, m is word count, k is word length
- Space Complexity: O(m * k)
31. Next Permutation
Description: Find the next lexicographically greater permutation of an array. If no such permutation exists, rearrange it to the lowest possible order (sorted in ascending order).
Java Solution:
public void nextPermutation(int[] nums) {
int i = nums.length - 2;
while (i >= 0 && nums[i] >= nums[i + 1]) i--;
if (i >= 0) {
int j = nums.length - 1;
while (nums[j] <= nums[i]) j--;
swap(nums, i, j);
}
reverse(nums, i + 1, nums.length - 1);
}
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
private void reverse(int[] nums, int start, int end) {
while (start < end) {
swap(nums, start++, end--);
}
}
Explanation: Find the first decreasing element from right, swap it with the next larger element, then reverse the suffix.
- Time Complexity: O(n)
- Space Complexity: O(1)
32. Longest Valid Parentheses
Description: Given a string containing just the characters ’(’ and ’)’, return the length of the longest valid (well-formed) parentheses substring.
Java Solution:
public int longestValidParentheses(String s) {
int maxLen = 0;
Stack<Integer> stack = new Stack<>();
stack.push(-1);
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
stack.push(i);
} else {
stack.pop();
if (stack.isEmpty()) {
stack.push(i);
} else {
maxLen = Math.max(maxLen, i - stack.peek());
}
}
}
return maxLen;
}
Explanation: Uses a stack to track indices. For ’(’, push index. For ’)’, pop and calculate length. Handle edge cases with dummy -1 at bottom.
- Time Complexity: O(n)
- Space Complexity: O(n)
33. Search in Rotated Sorted Array
Description: Given a rotated sorted array and a target value, return the index of the target if found, otherwise return -1. You must write an algorithm with O(log n) runtime complexity.
Java Solution:
public int 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) return mid;
if (nums[left] <= nums[mid]) {
if (nums[left] <= target && target < nums[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[right]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return -1;
}
Explanation: Modified binary search. Determine which half is sorted, then check if target is in that range.
- Time Complexity: O(log n)
- Space Complexity: O(1)
34. Find First and Last Position of Element in Sorted Array
Description: Given an array sorted in ascending order, find the starting and ending position of a given target value. If not found, return [-1, -1].
Java Solution:
public int[] searchRange(int[] nums, int target) {
int[] result = {-1, -1};
result[0] = findFirst(nums, target);
result[1] = findLast(nums, target);
return result;
}
private int findFirst(int[] nums, int target) {
int left = 0, right = nums.length - 1, result = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
result = mid;
right = mid - 1;
} else if (nums[mid] < target) left = mid + 1;
else right = mid - 1;
}
return result;
}
private int findLast(int[] nums, int target) {
int left = 0, right = nums.length - 1, result = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
result = mid;
left = mid + 1;
} else if (nums[mid] < target) left = mid + 1;
else right = mid - 1;
}
return result;
}
Explanation: Two binary searches: one for first occurrence (search left when found) and one for last (search right when found).
- Time Complexity: O(log n)
- Space Complexity: O(1)
35. Search Insert Position
Description: Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
Java Solution:
public int searchInsert(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left;
}
Explanation: Standard binary search. The left pointer will be at the insertion position when the loop ends.
- Time Complexity: O(log n)
- Space Complexity: O(1)
36. Valid Sudoku
Description: Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to Sudoku rules.
Java Solution:
public boolean isValidSudoku(char[][] board) {
Set<String> seen = new HashSet<>();
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
char num = board[i][j];
if (num != '.') {
if (!seen.add(num + " in row " + i) ||
!seen.add(num + " in col " + j) ||
!seen.add(num + " in box " + i/3 + "-" + j/3)) {
return false;
}
}
}
}
return true;
}
Explanation: Use a HashSet to track seen numbers in rows, columns, and 3x3 boxes. Add uniquely formatted strings for each constraint.
- Time Complexity: O(1) - fixed 9x9 board
- Space Complexity: O(1)
37. Sudoku Solver
Description: Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy all Sudoku rules.
Java Solution:
public void solveSudoku(char[][] board) {
solve(board);
}
private boolean solve(char[][] board) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] == '.') {
for (char c = '1'; c <= '9'; c++) {
if (isValid(board, i, j, c)) {
board[i][j] = c;
if (solve(board)) return true;
board[i][j] = '.';
}
}
return false;
}
}
}
return true;
}
private boolean isValid(char[][] board, int row, int col, char c) {
for (int i = 0; i < 9; i++) {
if (board[row][i] == c) return false;
if (board[i][col] == c) return false;
if (board[3*(row/3)+i/3][3*(col/3)+i%3] == c) return false;
}
return true;
}
Explanation: Backtracking algorithm that tries digits 1-9 for each empty cell, validates placement, and recursively solves remaining cells.
- Time Complexity: O(9^(n*n)) in worst case
- Space Complexity: O(n*n) for recursion
38. Count and Say
Description: The count-and-say sequence is a sequence of digit strings where each term is obtained by describing the previous term. Given a positive integer n, return the nth term.
Java Solution:
public String countAndSay(int n) {
String result = "1";
for (int i = 1; i < n; i++) {
result = getNext(result);
}
return result;
}
private String getNext(String s) {
StringBuilder sb = new StringBuilder();
int count = 1;
for (int i = 0; i < s.length(); i++) {
if (i + 1 < s.length() && s.charAt(i) == s.charAt(i + 1)) {
count++;
} else {
sb.append(count).append(s.charAt(i));
count = 1;
}
}
return sb.toString();
}
Explanation: Iteratively build each term by counting consecutive digits and appending count+digit pairs.
- Time Complexity: O(n * m) where m is length of each term
- Space Complexity: O(m)
39. Combination Sum
Description: Given an array of distinct integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target. The same number may be chosen unlimited times.
Java Solution:
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList<>();
backtrack(result, new ArrayList<>(), candidates, target, 0);
return result;
}
private void backtrack(List<List<Integer>> result, List<Integer> current,
int[] candidates, int remain, int start) {
if (remain < 0) return;
if (remain == 0) {
result.add(new ArrayList<>(current));
return;
}
for (int i = start; i < candidates.length; i++) {
current.add(candidates[i]);
backtrack(result, current, candidates, remain - candidates[i], i);
current.remove(current.size() - 1);
}
}
Explanation: Backtracking with pruning. Try each candidate, subtract from target, and recurse. Allow reuse by passing same index.
- Time Complexity: O(n^(target/min))
- Space Complexity: O(target/min) for recursion depth
40. Combination Sum II
Description: Given a collection of candidate numbers and a target, find all unique combinations where the candidate numbers sum to target. Each number in candidates may only be used once in the combination.
Java Solution:
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(candidates);
backtrack(result, new ArrayList<>(), candidates, target, 0);
return result;
}
private void backtrack(List<List<Integer>> result, List<Integer> current,
int[] candidates, int remain, int start) {
if (remain < 0) return;
if (remain == 0) {
result.add(new ArrayList<>(current));
return;
}
for (int i = start; i < candidates.length; i++) {
if (i > start && candidates[i] == candidates[i-1]) continue;
current.add(candidates[i]);
backtrack(result, current, candidates, remain - candidates[i], i + 1);
current.remove(current.size() - 1);
}
}
Explanation: Similar to Combination Sum but skip duplicates and use each element once by advancing start index.
- Time Complexity: O(2^n)
- Space Complexity: O(n)
41. First Missing Positive
Description: Given an unsorted integer array nums, return the smallest missing positive integer. You must implement an algorithm that runs in O(n) time and uses O(1) auxiliary space.
Java Solution:
public int firstMissingPositive(int[] nums) {
int n = nums.length;
for (int i = 0; i < n; i++) {
while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {
int temp = nums[nums[i] - 1];
nums[nums[i] - 1] = nums[i];
nums[i] = temp;
}
}
for (int i = 0; i < n; i++) {
if (nums[i] != i + 1) {
return i + 1;
}
}
return n + 1;
}
Explanation: Use the array itself as a hash table. Place each number at its corresponding index (nums[i] at index i-1). Then find the first index where nums[i] != i+1.
- Time Complexity: O(n)
- Space Complexity: O(1)
42. Trapping Rain Water
Description: Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.
Java Solution:
public int trap(int[] height) {
if (height == null || height.length == 0) return 0;
int left = 0, right = height.length - 1;
int leftMax = 0, rightMax = 0;
int water = 0;
while (left < right) {
if (height[left] < height[right]) {
if (height[left] >= leftMax) {
leftMax = height[left];
} else {
water += leftMax - height[left];
}
left++;
} else {
if (height[right] >= rightMax) {
rightMax = height[right];
} else {
water += rightMax - height[right];
}
right--;
}
}
return water;
}
Explanation: Two pointers approach. Track max heights from both sides. Water trapped at position is min(leftMax, rightMax) - height[i].
- Time Complexity: O(n)
- Space Complexity: O(1)
43. Multiply Strings
Description: Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2, also represented as a string. Note: You must not use any built-in BigInteger library or convert the inputs to integer directly.
Java Solution:
public String multiply(String num1, String num2) {
if (num1.equals("0") || num2.equals("0")) return "0";
int m = num1.length(), n = num2.length();
int[] result = new int[m + n];
for (int i = m - 1; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
int mul = (num1.charAt(i) - '0') * (num2.charAt(j) - '0');
int p1 = i + j, p2 = i + j + 1;
int sum = mul + result[p2];
result[p2] = sum % 10;
result[p1] += sum / 10;
}
}
StringBuilder sb = new StringBuilder();
for (int num : result) {
if (!(sb.length() == 0 && num == 0)) {
sb.append(num);
}
}
return sb.length() == 0 ? "0" : sb.toString();
}
Explanation: Simulate multiplication digit by digit, storing intermediate results in an array. Handle carries and leading zeros.
- Time Complexity: O(m * n)
- Space Complexity: O(m + n)
44. Wildcard Matching
Description: Given an input string (s) and a pattern (p), implement wildcard pattern matching with support for ’?’ and '' where ’?’ matches any single character and '' matches any sequence of characters.
Java Solution:
public boolean isMatch(String s, String p) {
int m = s.length(), n = p.length();
boolean[][] dp = new boolean[m + 1][n + 1];
dp[0][0] = true;
for (int j = 1; j <= n; j++) {
if (p.charAt(j - 1) == '*') {
dp[0][j] = dp[0][j - 1];
}
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (p.charAt(j - 1) == '*') {
dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
} else if (p.charAt(j - 1) == '?' || s.charAt(i - 1) == p.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1];
}
}
}
return dp[m][n];
}
Explanation: Dynamic programming. dp[i][j] represents if s[0..i-1] matches p[0..j-1]. Handle ’?’ and ’*’ cases separately.
- Time Complexity: O(m * n)
- Space Complexity: O(m * n)
45. Jump Game II
Description: Given an array of non-negative integers nums where you are initially positioned at the first index, each element represents your maximum jump length at that position. Your goal is to reach the last index in the minimum number of jumps.
Java Solution:
public int jump(int[] nums) {
int jumps = 0, currentEnd = 0, farthest = 0;
for (int i = 0; i < nums.length - 1; i++) {
farthest = Math.max(farthest, i + nums[i]);
if (i == currentEnd) {
jumps++;
currentEnd = farthest;
}
}
return jumps;
}
Explanation: Greedy approach. Track the farthest reachable position. When reaching the end of current jump range, increment jump count and update range.
- Time Complexity: O(n)
- Space Complexity: O(1)
46. Permutations
Description: Given an array nums of distinct integers, return all the possible permutations. You can return the answer in any order.
Java Solution:
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
backtrack(result, new ArrayList<>(), nums);
return result;
}
private void backtrack(List<List<Integer>> result, List<Integer> current, int[] nums) {
if (current.size() == nums.length) {
result.add(new ArrayList<>(current));
return;
}
for (int num : nums) {
if (current.contains(num)) continue;
current.add(num);
backtrack(result, current, nums);
current.remove(current.size() - 1);
}
}
Explanation: Backtracking to generate all permutations. Add element, recurse, remove element (backtrack).
- Time Complexity: O(n!)
- Space Complexity: O(n)
47. Permutations II
Description: Given a collection of numbers that might contain duplicates, return all possible unique permutations in any order.
Java Solution:
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
backtrack(result, new ArrayList<>(), nums, new boolean[nums.length]);
return result;
}
private void backtrack(List<List<Integer>> result, List<Integer> current, int[] nums, boolean[] used) {
if (current.size() == nums.length) {
result.add(new ArrayList<>(current));
return;
}
for (int i = 0; i < nums.length; i++) {
if (used[i] || (i > 0 && nums[i] == nums[i-1] && !used[i-1])) continue;
used[i] = true;
current.add(nums[i]);
backtrack(result, current, nums, used);
current.remove(current.size() - 1);
used[i] = false;
}
}
Explanation: Similar to Permutations but skip duplicates using sorted array and used array to avoid duplicate permutations.
- Time Complexity: O(n!)
- Space Complexity: O(n)
48. Rotate Image
Description: You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). You have to rotate the image in-place.
Java Solution:
public void rotate(int[][] matrix) {
int n = matrix.length;
// Transpose
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
// Reverse each row
for (int i = 0; i < n; i++) {
for (int j = 0; j < n / 2; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[i][n - 1 - j];
matrix[i][n - 1 - j] = temp;
}
}
}
Explanation: Transpose the matrix (swap rows and columns), then reverse each row to achieve 90-degree clockwise rotation.
- Time Complexity: O(n²)
- Space Complexity: O(1)
49. Group Anagrams
Description: Given an array of strings strs, group the anagrams together. You can return the answer in any order. An Anagram is a word formed by rearranging the letters of a different word.
Java Solution:
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<>();
for (String str : strs) {
char[] chars = str.toCharArray();
Arrays.sort(chars);
String key = String.valueOf(chars);
map.putIfAbsent(key, new ArrayList<>());
map.get(key).add(str);
}
return new ArrayList<>(map.values());
}
Explanation: Use sorted string as key in hash map. All anagrams will have the same sorted form, so they group together.
- Time Complexity: O(n * k log k) where n is number of strings and k is max length
- Space Complexity: O(n * k)
50. Pow(x, n)
Description: Implement pow(x, n), which calculates x raised to the power n (i.e., x^n).
Java Solution:
public double myPow(double x, int n) {
if (n == 0) return 1.0;
long N = n;
if (N < 0) {
x = 1 / x;
N = -N;
}
return fastPow(x, N);
}
private double fastPow(double x, long n) {
if (n == 0) return 1.0;
double half = fastPow(x, n / 2);
if (n % 2 == 0) {
return half * half;
} else {
return half * half * x;
}
}
Explanation: Binary exponentiation (fast power). Recursively compute x^(n/2) and square it. If n is odd, multiply by x once more.
- Time Complexity: O(log n)
- Space Complexity: O(log n) for recursion stack
51. N-Queens
Description: Place n queens on an n×n chessboard such that no two queens attack each other.
Java Solution:
public List<List<String>> solveNQueens(int n) {
List<List<String>> result = new ArrayList<>();
char[][] board = new char[n][n];
for (char[] row : board) Arrays.fill(row, '.');
backtrack(result, board, 0);
return result;
}
private void backtrack(List<List<String>> result, char[][] board, int row) {
if (row == board.length) {
result.add(construct(board));
return;
}
for (int col = 0; col < board.length; col++) {
if (isValid(board, row, col)) {
board[row][col] = 'Q';
backtrack(result, board, row + 1);
board[row][col] = '.';
}
}
}
private boolean isValid(char[][] board, int row, int col) {
for (int i = 0; i < row; i++)
if (board[i][col] == 'Q') return false;
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--)
if (board[i][j] == 'Q') return false;
for (int i = row - 1, j = col + 1; i >= 0 && j < board.length; i--, j++)
if (board[i][j] == 'Q') return false;
return true;
}
private List<String> construct(char[][] board) {
List<String> res = new ArrayList<>();
for (char[] row : board) res.add(new String(row));
return res;
}
Explanation: Use backtracking to place queens row by row. For each row, try placing a queen in each column and check if it’s valid (no conflicts with previously placed queens in same column or diagonals).
- Time Complexity: O(n!)
- Space Complexity: O(n²)
52. N-Queens II
Description: Return the number of distinct solutions to the n-queens puzzle.
Java Solution:
private int count = 0;
public int totalNQueens(int n) {
boolean[] cols = new boolean[n];
boolean[] diag1 = new boolean[2 * n];
boolean[] diag2 = new boolean[2 * n];
backtrack(0, n, cols, diag1, diag2);
return count;
}
private void backtrack(int row, int n, boolean[] cols, boolean[] diag1, boolean[] diag2) {
if (row == n) {
count++;
return;
}
for (int col = 0; col < n; col++) {
int d1 = row - col + n;
int d2 = row + col;
if (cols[col] || diag1[d1] || diag2[d2]) continue;
cols[col] = diag1[d1] = diag2[d2] = true;
backtrack(row + 1, n, cols, diag1, diag2);
cols[col] = diag1[d1] = diag2[d2] = false;
}
}
Explanation: Use boolean arrays to track occupied columns and diagonals for O(1) conflict checking. Count valid configurations without storing board states.
- Time Complexity: O(n!)
- Space Complexity: O(n)
53. Maximum Subarray
Description: Find the contiguous subarray with the largest sum.
Java Solution:
public int maxSubArray(int[] nums) {
int maxSum = nums[0];
int currentSum = nums[0];
for (int i = 1; i < nums.length; i++) {
currentSum = Math.max(nums[i], currentSum + nums[i]);
maxSum = Math.max(maxSum, currentSum);
}
return maxSum;
}
Explanation: Kadane’s algorithm: at each position, decide whether to start a new subarray or extend the existing one. Track the maximum sum seen so far.
- Time Complexity: O(n)
- Space Complexity: O(1)
54. Spiral Matrix
Description: Return all elements of a matrix in spiral order.
Java Solution:
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> result = new ArrayList<>();
if (matrix.length == 0) return result;
int top = 0, bottom = matrix.length - 1;
int left = 0, right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
for (int i = left; i <= right; i++) result.add(matrix[top][i]);
top++;
for (int i = top; i <= bottom; i++) result.add(matrix[i][right]);
right--;
if (top <= bottom) {
for (int i = right; i >= left; i--) result.add(matrix[bottom][i]);
bottom--;
}
if (left <= right) {
for (int i = bottom; i >= top; i--) result.add(matrix[i][left]);
left++;
}
}
return result;
}
Explanation: Use four boundaries (top, bottom, left, right) and traverse layer by layer, shrinking boundaries after each direction.
- Time Complexity: O(m×n)
- Space Complexity: O(1)
55. Jump Game
Description: Determine if you can reach the last index by jumping.
Java Solution:
public boolean canJump(int[] nums) {
int maxReach = 0;
for (int i = 0; i < nums.length; i++) {
if (i > maxReach) return false;
maxReach = Math.max(maxReach, i + nums[i]);
if (maxReach >= nums.length - 1) return true;
}
return true;
}
Explanation: Greedy approach: track the maximum reachable index. If current index exceeds max reach, we can’t proceed. If max reach covers the last index, return true.
- Time Complexity: O(n)
- Space Complexity: O(1)
56. Merge Intervals
Description: Merge all overlapping intervals.
Java Solution:
public int[][] merge(int[][] intervals) {
if (intervals.length <= 1) return intervals;
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
List<int[]> result = new ArrayList<>();
int[] current = intervals[0];
result.add(current);
for (int[] interval : intervals) {
if (interval[0] <= current[1]) {
current[1] = Math.max(current[1], interval[1]);
} else {
current = interval;
result.add(current);
}
}
return result.toArray(new int[result.size()][]);
}
Explanation: Sort intervals by start time, then merge overlapping intervals by extending the end time of the current interval.
- Time Complexity: O(n log n)
- Space Complexity: O(n)
57. Insert Interval
Description: Insert a new interval and merge if necessary.
Java Solution:
public int[][] insert(int[][] intervals, int[] newInterval) {
List<int[]> result = new ArrayList<>();
int i = 0;
while (i < intervals.length && intervals[i][1] < newInterval[0]) {
result.add(intervals[i++]);
}
while (i < intervals.length && intervals[i][0] <= newInterval[1]) {
newInterval[0] = Math.min(newInterval[0], intervals[i][0]);
newInterval[1] = Math.max(newInterval[1], intervals[i][1]);
i++;
}
result.add(newInterval);
while (i < intervals.length) {
result.add(intervals[i++]);
}
return result.toArray(new int[result.size()][]);
}
Explanation: Three phases: add intervals before new interval, merge overlapping intervals with new interval, add remaining intervals.
- Time Complexity: O(n)
- Space Complexity: O(n)
58. Length of Last Word
Description: Return the length of the last word in a string.
Java Solution:
public int lengthOfLastWord(String s) {
int length = 0;
int i = s.length() - 1;
while (i >= 0 && s.charAt(i) == ' ') i--;
while (i >= 0 && s.charAt(i) != ' ') {
length++;
i--;
}
return length;
}
Explanation: Scan from the end, skip trailing spaces, then count characters until the next space or beginning.
- Time Complexity: O(n)
- Space Complexity: O(1)
59. Spiral Matrix II
Description: Generate an n×n matrix filled with elements from 1 to n² in spiral order.
Java Solution:
public int[][] generateMatrix(int n) {
int[][] matrix = new int[n][n];
int top = 0, bottom = n - 1, left = 0, right = n - 1;
int num = 1;
while (top <= bottom && left <= right) {
for (int i = left; i <= right; i++) matrix[top][i] = num++;
top++;
for (int i = top; i <= bottom; i++) matrix[i][right] = num++;
right--;
for (int i = right; i >= left; i--) matrix[bottom][i] = num++;
bottom--;
for (int i = bottom; i >= top; i--) matrix[i][left] = num++;
left++;
}
return matrix;
}
Explanation: Fill the matrix layer by layer in spiral order using four boundaries, incrementing the value at each position.
- Time Complexity: O(n²)
- Space Complexity: O(1) excluding output
60. Permutation Sequence
Description: Return the kth permutation sequence of numbers 1 to n.
Java Solution:
public String getPermutation(int n, int k) {
List<Integer> nums = new ArrayList<>();
int[] factorial = new int[n + 1];
factorial[0] = 1;
for (int i = 1; i <= n; i++) {
factorial[i] = factorial[i - 1] * i;
nums.add(i);
}
k--;
StringBuilder sb = new StringBuilder();
for (int i = n; i > 0; i--) {
int index = k / factorial[i - 1];
sb.append(nums.get(index));
nums.remove(index);
k %= factorial[i - 1];
}
return sb.toString();
}
Explanation: Use factorial number system. For each position, determine which number to place by dividing k by (remaining positions)! to find the index in available numbers.
- Time Complexity: O(n²)
- Space Complexity: O(n)
61. Rotate List
Description: Rotate the list to the right by k places.
Java Solution:
public ListNode rotateRight(ListNode head, int k) {
if (head == null || head.next == null || k == 0) return head;
int length = 1;
ListNode tail = head;
while (tail.next != null) {
length++;
tail = tail.next;
}
k = k % length;
if (k == 0) return head;
tail.next = head;
int stepsToNewHead = length - k;
while (stepsToNewHead-- > 0) {
tail = tail.next;
}
head = tail.next;
tail.next = null;
return head;
}
Explanation: Find length and make circular. Calculate new head position as (length - k % length), then break the circle at the new tail.
- Time Complexity: O(n)
- Space Complexity: O(1)
62. Unique Paths
Description: Count paths from top-left to bottom-right in a grid.
Java Solution:
public int uniquePaths(int m, int n) {
int[] dp = new int[n];
Arrays.fill(dp, 1);
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[j] += dp[j - 1];
}
}
return dp[n - 1];
}
Explanation: Use 1D DP where dp[j] represents paths to reach column j. Each cell’s paths = paths from above + paths from left.
- Time Complexity: O(m×n)
- Space Complexity: O(n)
63. Unique Paths II
Description: Count paths in a grid with obstacles.
Java Solution:
public int uniquePathsWithObstacles(int[][] grid) {
int n = grid[0].length;
int[] dp = new int[n];
dp[0] = 1;
for (int[] row : grid) {
for (int j = 0; j < n; j++) {
if (row[j] == 1) {
dp[j] = 0;
} else if (j > 0) {
dp[j] += dp[j - 1];
}
}
}
return dp[n - 1];
}
Explanation: Similar to Unique Paths but set dp[j] = 0 when obstacle encountered. Continue path counting for non-obstacle cells.
- Time Complexity: O(m×n)
- Space Complexity: O(n)
64. Minimum Path Sum
Description: Find path with minimum sum from top-left to bottom-right.
Java Solution:
public int minPathSum(int[][] grid) {
int m = grid.length, n = grid[0].length;
for (int i = 1; i < m; i++) grid[i][0] += grid[i - 1][0];
for (int j = 1; j < n; j++) grid[0][j] += grid[0][j - 1];
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
grid[i][j] += Math.min(grid[i - 1][j], grid[i][j - 1]);
}
}
return grid[m - 1][n - 1];
}
Explanation: DP in-place. Each cell stores minimum sum to reach it from top-left, computed as current value plus minimum of top and left neighbors.
- Time Complexity: O(m×n)
- Space Complexity: O(1)
65. Valid Number
Description: Validate if a string represents a valid number.
Java Solution:
public boolean isNumber(String s) {
boolean numSeen = false, dotSeen = false, eSeen = false;
s = s.trim();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isDigit(c)) {
numSeen = true;
} else if (c == '.') {
if (dotSeen || eSeen) return false;
dotSeen = true;
} else if (c == 'e' || c == 'E') {
if (eSeen || !numSeen) return false;
eSeen = true;
numSeen = false;
} else if (c == '+' || c == '-') {
if (i != 0 && s.charAt(i - 1) != 'e' && s.charAt(i - 1) != 'E') return false;
} else {
return false;
}
}
return numSeen;
}
Explanation: Track what components we’ve seen (number, dot, exponent). Validate each character against the current state and update flags accordingly.
- Time Complexity: O(n)
- Space Complexity: O(1)
66. Plus One
Description: Increment a large integer represented as an array by one.
Java Solution:
public int[] plusOne(int[] digits) {
for (int i = digits.length - 1; i >= 0; i--) {
if (digits[i] < 9) {
digits[i]++;
return digits;
}
digits[i] = 0;
}
int[] result = new int[digits.length + 1];
result[0] = 1;
return result;
}
Explanation: Start from the end. If digit < 9, increment and return. If 9, set to 0 and continue. If all 9s, create new array with leading 1.
- Time Complexity: O(n)
- Space Complexity: O(1) or O(n) for overflow case
67. Add Binary
Description: Add two binary strings.
Java Solution:
public String addBinary(String a, String b) {
StringBuilder sb = new StringBuilder();
int i = a.length() - 1, j = b.length() - 1;
int carry = 0;
while (i >= 0 || j >= 0 || carry > 0) {
int sum = carry;
if (i >= 0) sum += a.charAt(i--) - '0';
if (j >= 0) sum += b.charAt(j--) - '0';
sb.append(sum % 2);
carry = sum / 2;
}
return sb.reverse().toString();
}
Explanation: Add bit by bit from right to left, tracking carry. Handle different lengths by continuing until both strings and carry are exhausted.
- Time Complexity: O(max(m, n))
- Space Complexity: O(max(m, n))
68. Text Justification
Description: Format text with full justification.
Java Solution:
public List<String> fullJustify(String[] words, int maxWidth) {
List<String> result = new ArrayList<>();
int i = 0;
while (i < words.length) {
int j = i, len = 0;
while (j < words.length && len + words[j].length() + (j - i) <= maxWidth) {
len += words[j++].length();
}
StringBuilder sb = new StringBuilder();
int spaces = maxWidth - len;
int gaps = j - i - 1;
for (int k = i; k < j; k++) {
sb.append(words[k]);
if (k < j - 1) {
int spaceCount = (j == words.length) ? 1 : (spaces / gaps + (k - i < spaces % gaps ? 1 : 0));
for (int s = 0; s < spaceCount; s++) sb.append(' ');
spaces -= (j == words.length) ? 1 : spaceCount;
gaps--;
}
}
while (sb.length() < maxWidth) sb.append(' ');
result.add(sb.toString());
i = j;
}
return result;
}
Explanation: Greedily pack words into lines. Distribute spaces evenly between words, with extra spaces going to left gaps. Last line is left-justified.
- Time Complexity: O(n) where n is total characters
- Space Complexity: O(maxWidth)
69. Sqrt(x)
Description: Compute the square root of x.
Java Solution:
public int mySqrt(int x) {
if (x < 2) return x;
long left = 1, right = x / 2;
while (left <= right) {
long mid = left + (right - left) / 2;
long sq = mid * mid;
if (sq == x) return (int) mid;
if (sq < x) left = mid + 1;
else right = mid - 1;
}
return (int) right;
}
Explanation: Binary search for the largest integer whose square is ≤ x. Use long to avoid overflow during multiplication.
- Time Complexity: O(log n)
- Space Complexity: O(1)
70. Climbing Stairs
Description: Count ways to climb n stairs taking 1 or 2 steps.
Java Solution:
public int climbStairs(int n) {
if (n <= 2) return n;
int prev2 = 1, prev1 = 2;
for (int i = 3; i <= n; i++) {
int current = prev1 + prev2;
prev2 = prev1;
prev1 = current;
}
return prev1;
}
Explanation: Fibonacci sequence: ways to reach step n = ways to reach (n-1) + ways to reach (n-2). Use two variables for O(1) space.
- Time Complexity: O(n)
- Space Complexity: O(1)
71. Simplify Path
Description: Simplify an absolute Unix-style file path.
Java Solution:
public String simplifyPath(String path) {
Deque<String> stack = new ArrayDeque<>();
String[] parts = path.split("/");
for (String part : parts) {
if (part.equals("..")) {
if (!stack.isEmpty()) stack.pop();
} else if (!part.isEmpty() && !part.equals(".")) {
stack.push(part);
}
}
StringBuilder result = new StringBuilder();
while (!stack.isEmpty()) {
result.insert(0, "/" + stack.pop());
}
return result.length() == 0 ? "/" : result.toString();
}
Explanation: Split by ”/”, use stack to track directories. ”..” pops, ”.” and empty strings are skipped, everything else is pushed.
- Time Complexity: O(n)
- Space Complexity: O(n)
72. Edit Distance
Description: Find minimum edit distance between two strings.
Java Solution:
public int minDistance(String word1, String word2) {
int m = word1.length(), n = word2.length();
int[][] dp = new int[m + 1][n + 1];
for (int i = 0; i <= m; i++) dp[i][0] = i;
for (int j = 0; j <= n; j++) dp[0][j] = j;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = 1 + Math.min(dp[i - 1][j - 1],
Math.min(dp[i - 1][j], dp[i][j - 1]));
}
}
}
return dp[m][n];
}
Explanation: DP where dp[i][j] is min operations to convert word1[0..i-1] to word2[0..j-1]. If chars match, no operation needed; otherwise take min of replace, delete, or insert.
- Time Complexity: O(m×n)
- Space Complexity: O(m×n)
73. Set Matrix Zeroes
Description: Set entire row and column to zero if element is zero.
Java Solution:
public void setZeroes(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
boolean firstRowZero = false, firstColZero = false;
for (int j = 0; j < n; j++) if (matrix[0][j] == 0) firstRowZero = true;
for (int i = 0; i < m; i++) if (matrix[i][0] == 0) firstColZero = true;
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (matrix[i][j] == 0) {
matrix[i][0] = 0;
matrix[0][j] = 0;
}
}
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (matrix[i][0] == 0 || matrix[0][j] == 0) {
matrix[i][j] = 0;
}
}
}
if (firstRowZero) for (int j = 0; j < n; j++) matrix[0][j] = 0;
if (firstColZero) for (int i = 0; i < m; i++) matrix[i][0] = 0;
}
Explanation: Use first row and column as markers. Track if first row/col originally had zeros. Mark zeros, then fill based on markers.
- Time Complexity: O(m×n)
- Space Complexity: O(1)
74. Search a 2D Matrix
Description: Search for a value in a sorted 2D matrix.
Java Solution:
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length, n = matrix[0].length;
int left = 0, right = m * n - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
int val = matrix[mid / n][mid % n];
if (val == target) return true;
if (val < target) left = mid + 1;
else right = mid - 1;
}
return false;
}
Explanation: Treat the 2D matrix as a sorted 1D array. Use binary search with index conversion: row = index / cols, col = index % cols.
- Time Complexity: O(log(m×n))
- Space Complexity: O(1)
75. Sort Colors
Description: Sort array with values 0, 1, 2 in-place (Dutch National Flag problem).
Java Solution:
public void sortColors(int[] nums) {
int low = 0, mid = 0, high = nums.length - 1;
while (mid <= high) {
if (nums[mid] == 0) {
swap(nums, low++, mid++);
} else if (nums[mid] == 1) {
mid++;
} else {
swap(nums, mid, high--);
}
}
}
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
Explanation: Three pointers: low (next 0 position), mid (current), high (next 2 position). Swap 0s to front, 2s to back, 1s stay in middle.
- Time Complexity: O(n)
- Space Complexity: O(1)
76. Minimum Window Substring
Description: Find minimum window containing all characters of target.
Java Solution:
public String minWindow(String s, String t) {
int[] need = new int[128], have = new int[128];
for (char c : t.toCharArray()) need[c]++;
int required = 0;
for (int n : need) if (n > 0) required++;
int left = 0, formed = 0, minLen = Integer.MAX_VALUE, start = 0;
for (int right = 0; right < s.length(); right++) {
char c = s.charAt(right);
have[c]++;
if (need[c] > 0 && have[c] == need[c]) formed++;
while (formed == required) {
if (right - left + 1 < minLen) {
minLen = right - left + 1;
start = left;
}
char leftChar = s.charAt(left++);
if (need[leftChar] > 0 && have[leftChar] == need[leftChar]) formed--;
have[leftChar]--;
}
}
return minLen == Integer.MAX_VALUE ? "" : s.substring(start, start + minLen);
}
Explanation: Sliding window with character frequency tracking. Expand right to include all required chars, shrink left to find minimum valid window.
- Time Complexity: O(m + n)
- Space Complexity: O(1) - fixed size array
77. Combinations
Description: Generate all combinations of k numbers from 1 to n.
Java Solution:
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> result = new ArrayList<>();
backtrack(result, new ArrayList<>(), 1, n, k);
return result;
}
private void backtrack(List<List<Integer>> result, List<Integer> curr, int start, int n, int k) {
if (curr.size() == k) {
result.add(new ArrayList<>(curr));
return;
}
for (int i = start; i <= n - (k - curr.size()) + 1; i++) {
curr.add(i);
backtrack(result, curr, i + 1, n, k);
curr.remove(curr.size() - 1);
}
}
Explanation: Backtracking with pruning. Only iterate up to n - (k - curr.size()) + 1 to ensure enough numbers remain to complete the combination.
- Time Complexity: O(k × C(n,k))
- Space Complexity: O(k)
78. Subsets
Description: Generate all possible subsets.
Java Solution:
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
backtrack(result, new ArrayList<>(), nums, 0);
return result;
}
private void backtrack(List<List<Integer>> result, List<Integer> curr, int[] nums, int start) {
result.add(new ArrayList<>(curr));
for (int i = start; i < nums.length; i++) {
curr.add(nums[i]);
backtrack(result, curr, nums, i + 1);
curr.remove(curr.size() - 1);
}
}
Explanation: Backtracking: at each step, add current subset to result, then try adding each remaining element. Each element is either included or not.
- Time Complexity: O(n × 2^n)
- Space Complexity: O(n)
79. Word Search
Description: Find if word exists in grid.
Java Solution:
public boolean exist(char[][] board, String word) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (dfs(board, word, i, j, 0)) return true;
}
}
return false;
}
private boolean dfs(char[][] board, String word, int i, int j, int k) {
if (k == word.length()) return true;
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length) return false;
if (board[i][j] != word.charAt(k)) return false;
char temp = board[i][j];
board[i][j] = '#';
boolean found = dfs(board, word, i + 1, j, k + 1) ||
dfs(board, word, i - 1, j, k + 1) ||
dfs(board, word, i, j + 1, k + 1) ||
dfs(board, word, i, j - 1, k + 1);
board[i][j] = temp;
return found;
}
Explanation: DFS backtracking from each cell. Mark visited cells temporarily to avoid reuse. Restore cell after exploring all paths.
- Time Complexity: O(m × n × 4^L)
- Space Complexity: O(L) for recursion
80. Remove Duplicates from Sorted Array II
Description: Remove duplicates allowing at most 2 occurrences.
Java Solution:
public int removeDuplicates(int[] nums) {
if (nums.length <= 2) return nums.length;
int k = 2;
for (int i = 2; i < nums.length; i++) {
if (nums[i] != nums[k - 2]) {
nums[k++] = nums[i];
}
}
return k;
}
Explanation: Two pointers: k tracks position to write. Only write current element if it differs from element at k-2 (allowing at most 2 duplicates).
- Time Complexity: O(n)
- Space Complexity: O(1)
81. Search in Rotated Sorted Array II
Description: Search in rotated array with duplicates.
Java Solution:
public boolean 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) return true;
if (nums[left] == nums[mid] && nums[mid] == nums[right]) {
left++;
right--;
} else if (nums[left] <= nums[mid]) {
if (nums[left] <= target && target < nums[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[right]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return false;
}
Explanation: Modified binary search. When duplicates create ambiguity (nums[left] == nums[mid] == nums[right]), shrink both ends. Otherwise, determine which half is sorted.
- Time Complexity: O(n) worst case, O(log n) average
- Space Complexity: O(1)
82. Remove Duplicates from Sorted List II
Description: Remove all nodes with duplicate values from linked list.
Java Solution:
public ListNode deleteDuplicates(ListNode head) {
ListNode dummy = new ListNode(0, head);
ListNode prev = dummy;
while (head != null) {
if (head.next != null && head.val == head.next.val) {
while (head.next != null && head.val == head.next.val) {
head = head.next;
}
prev.next = head.next;
} else {
prev = prev.next;
}
head = head.next;
}
return dummy.next;
}
Explanation: Use dummy node to handle head removal. Skip all nodes with duplicate values by advancing until different value found.
- Time Complexity: O(n)
- Space Complexity: O(1)
83. Remove Duplicates from Sorted List
Description: Remove duplicates keeping one copy of each value.
Java Solution:
public ListNode deleteDuplicates(ListNode head) {
ListNode current = head;
while (current != null && current.next != null) {
if (current.val == current.next.val) {
current.next = current.next.next;
} else {
current = current.next;
}
}
return head;
}
Explanation: Single pass: when duplicate found, skip the next node by updating pointer. Otherwise, move to next node.
- Time Complexity: O(n)
- Space Complexity: O(1)
84. Largest Rectangle in Histogram
Description: Find largest rectangle in histogram.
Java Solution:
public int largestRectangleArea(int[] heights) {
Deque<Integer> stack = new ArrayDeque<>();
int maxArea = 0;
int n = heights.length;
for (int i = 0; i <= n; i++) {
int h = (i == n) ? 0 : heights[i];
while (!stack.isEmpty() && h < heights[stack.peek()]) {
int height = heights[stack.pop()];
int width = stack.isEmpty() ? i : i - stack.peek() - 1;
maxArea = Math.max(maxArea, height * width);
}
stack.push(i);
}
return maxArea;
}
Explanation: Monotonic increasing stack stores indices. When smaller height found, pop and calculate area using popped height and width determined by current index and new stack top.
- Time Complexity: O(n)
- Space Complexity: O(n)
85. Maximal Rectangle
Description: Find largest rectangle containing only 1s in binary matrix.
Java Solution:
public int maximalRectangle(char[][] matrix) {
if (matrix.length == 0) return 0;
int n = matrix[0].length;
int[] heights = new int[n];
int maxArea = 0;
for (char[] row : matrix) {
for (int j = 0; j < n; j++) {
heights[j] = row[j] == '1' ? heights[j] + 1 : 0;
}
maxArea = Math.max(maxArea, largestRectangleArea(heights));
}
return maxArea;
}
private int largestRectangleArea(int[] heights) {
Deque<Integer> stack = new ArrayDeque<>();
int maxArea = 0;
for (int i = 0; i <= heights.length; i++) {
int h = (i == heights.length) ? 0 : heights[i];
while (!stack.isEmpty() && h < heights[stack.peek()]) {
int height = heights[stack.pop()];
int width = stack.isEmpty() ? i : i - stack.peek() - 1;
maxArea = Math.max(maxArea, height * width);
}
stack.push(i);
}
return maxArea;
}
Explanation: Build histogram row by row where height[j] is consecutive 1s above including current cell. Apply largest rectangle in histogram for each row.
- Time Complexity: O(m×n)
- Space Complexity: O(n)
86. Partition List
Description: Partition linked list around value x.
Java Solution:
public ListNode partition(ListNode head, int x) {
ListNode beforeHead = new ListNode(0);
ListNode afterHead = new ListNode(0);
ListNode before = beforeHead, after = afterHead;
while (head != null) {
if (head.val < x) {
before.next = head;
before = before.next;
} else {
after.next = head;
after = after.next;
}
head = head.next;
}
after.next = null;
before.next = afterHead.next;
return beforeHead.next;
}
Explanation: Create two lists: one for nodes < x, one for nodes >= x. Traverse original list, appending to appropriate list. Connect before list to after list.
- Time Complexity: O(n)
- Space Complexity: O(1)
87. Scramble String
Description: Check if s2 is a scrambled string of s1.
Java Solution:
Map<String, Boolean> memo = new HashMap<>();
public boolean isScramble(String s1, String s2) {
if (s1.equals(s2)) return true;
if (s1.length() != s2.length()) return false;
String key = s1 + "#" + s2;
if (memo.containsKey(key)) return memo.get(key);
int[] count = new int[26];
for (int i = 0; i < s1.length(); i++) {
count[s1.charAt(i) - 'a']++;
count[s2.charAt(i) - 'a']--;
}
for (int c : count) if (c != 0) { memo.put(key, false); return false; }
for (int i = 1; i < s1.length(); i++) {
if (isScramble(s1.substring(0, i), s2.substring(0, i)) &&
isScramble(s1.substring(i), s2.substring(i))) {
memo.put(key, true);
return true;
}
if (isScramble(s1.substring(0, i), s2.substring(s2.length() - i)) &&
isScramble(s1.substring(i), s2.substring(0, s2.length() - i))) {
memo.put(key, true);
return true;
}
}
memo.put(key, false);
return false;
}
Explanation: Recursively check if any split produces matching scrambles (either same order or swapped). Memoize results and prune with character count check.
- Time Complexity: O(n^4)
- Space Complexity: O(n^3)
88. Merge Sorted Array
Description: Merge two sorted arrays in-place.
Java Solution:
public void merge(int[] nums1, int m, int[] nums2, int n) {
int i = m - 1, j = n - 1, k = m + n - 1;
while (j >= 0) {
if (i >= 0 && nums1[i] > nums2[j]) {
nums1[k--] = nums1[i--];
} else {
nums1[k--] = nums2[j--];
}
}
}
Explanation: Merge from the end to avoid overwriting unprocessed elements. Compare largest unmerged elements and place at the end of nums1.
- Time Complexity: O(m + n)
- Space Complexity: O(1)
89. Gray Code
Description: Generate n-bit Gray code sequence.
Java Solution:
public List<Integer> grayCode(int n) {
List<Integer> result = new ArrayList<>();
result.add(0);
for (int i = 0; i < n; i++) {
int size = result.size();
int mask = 1 << i;
for (int j = size - 1; j >= 0; j--) {
result.add(result.get(j) | mask);
}
}
return result;
}
Explanation: Build iteratively. For each bit position, mirror existing sequence and set the new bit. This ensures adjacent codes differ by one bit.
- Time Complexity: O(2^n)
- Space Complexity: O(1) excluding output
90. Subsets II
Description: Generate all subsets with duplicates in input handled.
Java Solution:
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
backtrack(result, new ArrayList<>(), nums, 0);
return result;
}
private void backtrack(List<List<Integer>> result, List<Integer> curr, int[] nums, int start) {
result.add(new ArrayList<>(curr));
for (int i = start; i < nums.length; i++) {
if (i > start && nums[i] == nums[i - 1]) continue;
curr.add(nums[i]);
backtrack(result, curr, nums, i + 1);
curr.remove(curr.size() - 1);
}
}
Explanation: Sort array first. During backtracking, skip duplicates at the same level (when i > start and nums[i] == nums[i-1]) to avoid duplicate subsets.
- Time Complexity: O(n × 2^n)
- Space Complexity: O(n)
91. Decode Ways
Description: Count ways to decode a digit string where ‘A’ = 1, ‘B’ = 2, …, ‘Z’ = 26.
Java Solution:
public int numDecodings(String s) {
if (s.isEmpty() || s.charAt(0) == '0') return 0;
int prev2 = 1, prev1 = 1;
for (int i = 1; i < s.length(); i++) {
int curr = 0;
int oneDigit = s.charAt(i) - '0';
int twoDigit = Integer.parseInt(s.substring(i - 1, i + 1));
if (oneDigit >= 1) curr += prev1;
if (twoDigit >= 10 && twoDigit <= 26) curr += prev2;
prev2 = prev1;
prev1 = curr;
}
return prev1;
}
Explanation: DP with O(1) space. At each position, count ways using single digit (1-9) and two digits (10-26). Sum valid decodings from previous states.
- Time Complexity: O(n)
- Space Complexity: O(1)
92. Reverse Linked List II
Description: Reverse nodes from position left to right in linked list.
Java Solution:
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode(0, head);
ListNode prev = dummy;
for (int i = 1; i < left; i++) prev = prev.next;
ListNode curr = prev.next;
for (int i = 0; i < right - left; i++) {
ListNode next = curr.next;
curr.next = next.next;
next.next = prev.next;
prev.next = next;
}
return dummy.next;
}
Explanation: Navigate to position before left. Then repeatedly move the next node to the front of the reversed section using pointer manipulation.
- Time Complexity: O(n)
- Space Complexity: O(1)
93. Restore IP Addresses
Description: Generate all valid IP addresses from a digit string.
Java Solution:
public List<String> restoreIpAddresses(String s) {
List<String> result = new ArrayList<>();
backtrack(result, s, 0, new ArrayList<>());
return result;
}
private void backtrack(List<String> result, String s, int start, List<String> parts) {
if (parts.size() == 4) {
if (start == s.length()) {
result.add(String.join(".", parts));
}
return;
}
for (int len = 1; len <= 3 && start + len <= s.length(); len++) {
String part = s.substring(start, start + len);
if ((part.length() > 1 && part.startsWith("0")) || Integer.parseInt(part) > 255) continue;
parts.add(part);
backtrack(result, s, start + len, parts);
parts.remove(parts.size() - 1);
}
}
Explanation: Backtracking: try all valid segment lengths (1-3 digits). Validate each segment (no leading zeros except “0”, value ≤ 255). Must use all digits in exactly 4 parts.
- Time Complexity: O(1) - bounded by IP format
- Space Complexity: O(1)
94. Binary Tree Inorder Traversal
Description: Return inorder traversal of binary tree.
Java Solution:
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
TreeNode curr = root;
while (curr != null || !stack.isEmpty()) {
while (curr != null) {
stack.push(curr);
curr = curr.left;
}
curr = stack.pop();
result.add(curr.val);
curr = curr.right;
}
return result;
}
Explanation: Iterative approach using stack. Go left as far as possible, then process node and go right. Stack maintains nodes to return to.
- Time Complexity: O(n)
- Space Complexity: O(n)
95. Unique Binary Search Trees II
Description: Generate all structurally unique BSTs with n nodes.
Java Solution:
public List<TreeNode> generateTrees(int n) {
if (n == 0) return new ArrayList<>();
return generate(1, n);
}
private List<TreeNode> generate(int start, int end) {
List<TreeNode> trees = new ArrayList<>();
if (start > end) {
trees.add(null);
return trees;
}
for (int i = start; i <= end; i++) {
List<TreeNode> leftTrees = generate(start, i - 1);
List<TreeNode> rightTrees = generate(i + 1, end);
for (TreeNode left : leftTrees) {
for (TreeNode right : rightTrees) {
TreeNode root = new TreeNode(i);
root.left = left;
root.right = right;
trees.add(root);
}
}
}
return trees;
}
Explanation: Recursively generate all left and right subtrees for each root value. Combine all left-right pairs to form complete trees.
- Time Complexity: O(4^n / n^(3/2)) - Catalan number
- Space Complexity: O(4^n / n^(3/2))
96. Unique Binary Search Trees
Description: Count unique BSTs with n nodes.
Java Solution:
public int numTrees(int n) {
int[] dp = new int[n + 1];
dp[0] = dp[1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i; j++) {
dp[i] += dp[j - 1] * dp[i - j];
}
}
return dp[n];
}
Explanation: Catalan number formula: G(n) = Σ G(i-1) × G(n-i) for i from 1 to n. dp[i] counts BSTs with i nodes. Each root splits remaining nodes.
- Time Complexity: O(n²)
- Space Complexity: O(n)
97. Interleaving String
Description: Check if s3 is formed by interleaving s1 and s2.
Java Solution:
public boolean isInterleave(String s1, String s2, String s3) {
int m = s1.length(), n = s2.length();
if (m + n != s3.length()) return false;
boolean[] dp = new boolean[n + 1];
dp[0] = true;
for (int j = 1; j <= n; j++) {
dp[j] = dp[j - 1] && s2.charAt(j - 1) == s3.charAt(j - 1);
}
for (int i = 1; i <= m; i++) {
dp[0] = dp[0] && s1.charAt(i - 1) == s3.charAt(i - 1);
for (int j = 1; j <= n; j++) {
dp[j] = (dp[j] && s1.charAt(i - 1) == s3.charAt(i + j - 1)) ||
(dp[j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1));
}
}
return dp[n];
}
Explanation: DP where dp[j] indicates if s1[0..i-1] and s2[0..j-1] can form s3[0..i+j-1]. Check if current char from s1 or s2 matches s3.
- Time Complexity: O(m×n)
- Space Complexity: O(n)
98. Validate Binary Search Tree
Description: Check if tree is a valid BST.
Java Solution:
public boolean isValidBST(TreeNode root) {
return validate(root, null, null);
}
private boolean validate(TreeNode node, Integer min, Integer max) {
if (node == null) return true;
if (min != null && node.val <= min) return false;
if (max != null && node.val >= max) return false;
return validate(node.left, min, node.val) && validate(node.right, node.val, max);
}
Explanation: Recursively validate with bounds. Each node must be within (min, max) range. Left subtree has max = parent value, right subtree has min = parent value.
- Time Complexity: O(n)
- Space Complexity: O(h)
99. Recover Binary Search Tree
Description: Fix two swapped nodes in BST.
Java Solution:
private TreeNode first, second, prev;
public void recoverTree(TreeNode root) {
inorder(root);
int temp = first.val;
first.val = second.val;
second.val = temp;
}
private void inorder(TreeNode node) {
if (node == null) return;
inorder(node.left);
if (prev != null && prev.val > node.val) {
if (first == null) first = prev;
second = node;
}
prev = node;
inorder(node.right);
}
Explanation: Inorder traversal should be sorted. Find two violations: first is the larger node in first violation, second is the smaller node in last violation. Swap their values.
- Time Complexity: O(n)
- Space Complexity: O(h)
100. Same Tree
Description: Check if two trees are identical.
Java Solution:
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
if (p.val != q.val) return false;
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
Explanation: Recursively compare: both null = same, one null = different, values differ = different, otherwise check both subtrees match.
- Time Complexity: O(n)
- Space Complexity: O(h)
101. Symmetric Tree
Description: Check if a binary tree is symmetric around its center.
Java Solution:
public boolean isSymmetric(TreeNode root) {
return isMirror(root, root);
}
private boolean isMirror(TreeNode t1, TreeNode t2) {
if (t1 == null && t2 == null) return true;
if (t1 == null || t2 == null) return false;
return t1.val == t2.val && isMirror(t1.left, t2.right) && isMirror(t1.right, t2.left);
}
Explanation: Recursively check if left subtree mirrors right subtree. Two trees mirror if roots equal and left of one equals right of other.
- Time Complexity: O(n)
- Space Complexity: O(h)
102. Binary Tree Level Order Traversal
Description: Return level order traversal of binary tree as nested list.
Java Solution:
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) return result;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> level = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
level.add(node.val);
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
result.add(level);
}
return result;
}
Explanation: BFS using queue. Process all nodes at current level before moving to next. Track level size to know when level ends.
- Time Complexity: O(n)
- Space Complexity: O(n)
103. Binary Tree Zigzag Level Order Traversal
Description: Return zigzag level order traversal (alternating left-right, right-left).
Java Solution:
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) return result;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
boolean leftToRight = true;
while (!queue.isEmpty()) {
int size = queue.size();
LinkedList<Integer> level = new LinkedList<>();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
if (leftToRight) level.addLast(node.val);
else level.addFirst(node.val);
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
result.add(level);
leftToRight = !leftToRight;
}
return result;
}
Explanation: BFS with direction flag. On even levels add to end, on odd levels add to front using LinkedList for O(1) front insertion.
- Time Complexity: O(n)
- Space Complexity: O(n)
104. Maximum Depth of Binary Tree
Description: Return the maximum depth of a binary tree.
Java Solution:
public int maxDepth(TreeNode root) {
if (root == null) return 0;
return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
}
Explanation: Recursively compute depth as 1 + max of left and right subtree depths. Base case: null node has depth 0.
- Time Complexity: O(n)
- Space Complexity: O(h)
105. Construct Binary Tree from Preorder and Inorder Traversal
Description: Build a binary tree from preorder and inorder traversal arrays.
Java Solution:
private int preIdx = 0;
private Map<Integer, Integer> inMap = new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
for (int i = 0; i < inorder.length; i++) {
inMap.put(inorder[i], i);
}
return build(preorder, 0, inorder.length - 1);
}
private TreeNode build(int[] preorder, int left, int right) {
if (left > right) return null;
int rootVal = preorder[preIdx++];
TreeNode root = new TreeNode(rootVal);
int inIdx = inMap.get(rootVal);
root.left = build(preorder, left, inIdx - 1);
root.right = build(preorder, inIdx + 1, right);
return root;
}
Explanation: Preorder first element is root. Find root in inorder to split left/right subtrees. Use hashmap for O(1) lookup.
- Time Complexity: O(n)
- Space Complexity: O(n)
106. Construct Binary Tree from Inorder and Postorder Traversal
Description: Build a binary tree from inorder and postorder traversal arrays.
Java Solution:
private int postIdx;
private Map<Integer, Integer> inMap = new HashMap<>();
public TreeNode buildTree(int[] inorder, int[] postorder) {
postIdx = postorder.length - 1;
for (int i = 0; i < inorder.length; i++) {
inMap.put(inorder[i], i);
}
return build(postorder, 0, inorder.length - 1);
}
private TreeNode build(int[] postorder, int left, int right) {
if (left > right) return null;
int rootVal = postorder[postIdx--];
TreeNode root = new TreeNode(rootVal);
int inIdx = inMap.get(rootVal);
root.right = build(postorder, inIdx + 1, right);
root.left = build(postorder, left, inIdx - 1);
return root;
}
Explanation: Postorder last element is root. Build right subtree first (postorder processes right before left when reversed).
- Time Complexity: O(n)
- Space Complexity: O(n)
107. Binary Tree Level Order Traversal II
Description: Return bottom-up level order traversal.
Java Solution:
public List<List<Integer>> levelOrderBottom(TreeNode root) {
LinkedList<List<Integer>> result = new LinkedList<>();
if (root == null) return result;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> level = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
level.add(node.val);
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
result.addFirst(level);
}
return result;
}
Explanation: Standard BFS level order, but add each level to the front of result list for bottom-up order.
- Time Complexity: O(n)
- Space Complexity: O(n)
108. Convert Sorted Array to Binary Search Tree
Description: Convert sorted array to height-balanced BST.
Java Solution:
public TreeNode sortedArrayToBST(int[] nums) {
return build(nums, 0, nums.length - 1);
}
private TreeNode build(int[] nums, int left, int right) {
if (left > right) return null;
int mid = left + (right - left) / 2;
TreeNode root = new TreeNode(nums[mid]);
root.left = build(nums, left, mid - 1);
root.right = build(nums, mid + 1, right);
return root;
}
Explanation: Choose middle element as root for balance. Recursively build left and right subtrees from left and right halves.
- Time Complexity: O(n)
- Space Complexity: O(log n)
109. Convert Sorted List to Binary Search Tree
Description: Convert sorted linked list to height-balanced BST.
Java Solution:
public TreeNode sortedListToBST(ListNode head) {
if (head == null) return null;
if (head.next == null) return new TreeNode(head.val);
ListNode slow = head, fast = head, prev = null;
while (fast != null && fast.next != null) {
prev = slow;
slow = slow.next;
fast = fast.next.next;
}
prev.next = null;
TreeNode root = new TreeNode(slow.val);
root.left = sortedListToBST(head);
root.right = sortedListToBST(slow.next);
return root;
}
Explanation: Find middle using slow/fast pointers. Middle becomes root. Recursively build subtrees from left and right halves.
- Time Complexity: O(n log n)
- Space Complexity: O(log n)
110. Balanced Binary Tree
Description: Check if binary tree is height-balanced.
Java Solution:
public boolean isBalanced(TreeNode root) {
return height(root) != -1;
}
private int height(TreeNode node) {
if (node == null) return 0;
int left = height(node.left);
if (left == -1) return -1;
int right = height(node.right);
if (right == -1) return -1;
if (Math.abs(left - right) > 1) return -1;
return 1 + Math.max(left, right);
}
Explanation: Return -1 if unbalanced, otherwise return height. Early termination when imbalance detected.
- Time Complexity: O(n)
- Space Complexity: O(h)
111. Minimum Depth of Binary Tree
Description: Find minimum depth (path to nearest leaf).
Java Solution:
public int minDepth(TreeNode root) {
if (root == null) return 0;
if (root.left == null) return 1 + minDepth(root.right);
if (root.right == null) return 1 + minDepth(root.left);
return 1 + Math.min(minDepth(root.left), minDepth(root.right));
}
Explanation: Handle cases where one child is null (must go to other child). Otherwise take minimum of both subtrees.
- Time Complexity: O(n)
- Space Complexity: O(h)
112. Path Sum
Description: Check if tree has root-to-leaf path with given sum.
Java Solution:
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) return false;
if (root.left == null && root.right == null) return root.val == targetSum;
return hasPathSum(root.left, targetSum - root.val) ||
hasPathSum(root.right, targetSum - root.val);
}
Explanation: Subtract current value from target. At leaf, check if remaining target equals leaf value.
- Time Complexity: O(n)
- Space Complexity: O(h)
113. Path Sum II
Description: Find all root-to-leaf paths that sum to target.
Java Solution:
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
List<List<Integer>> result = new ArrayList<>();
dfs(root, targetSum, new ArrayList<>(), result);
return result;
}
private void dfs(TreeNode node, int sum, List<Integer> path, List<List<Integer>> result) {
if (node == null) return;
path.add(node.val);
if (node.left == null && node.right == null && sum == node.val) {
result.add(new ArrayList<>(path));
}
dfs(node.left, sum - node.val, path, result);
dfs(node.right, sum - node.val, path, result);
path.remove(path.size() - 1);
}
Explanation: Backtracking DFS. Track current path, add to result when leaf reached with matching sum.
- Time Complexity: O(n²)
- Space Complexity: O(n)
114. Flatten Binary Tree to Linked List
Description: Flatten binary tree to linked list in-place (preorder).
Java Solution:
public void flatten(TreeNode root) {
TreeNode curr = root;
while (curr != null) {
if (curr.left != null) {
TreeNode rightmost = curr.left;
while (rightmost.right != null) {
rightmost = rightmost.right;
}
rightmost.right = curr.right;
curr.right = curr.left;
curr.left = null;
}
curr = curr.right;
}
}
Explanation: For each node with left child: find rightmost of left subtree, connect it to right child, move left subtree to right, clear left.
- Time Complexity: O(n)
- Space Complexity: O(1)
115. Distinct Subsequences
Description: Count distinct subsequences of s that equal t.
Java Solution:
public int numDistinct(String s, String t) {
int m = s.length(), n = t.length();
int[] dp = new int[n + 1];
dp[0] = 1;
for (int i = 1; i <= m; i++) {
for (int j = n; j >= 1; j--) {
if (s.charAt(i - 1) == t.charAt(j - 1)) {
dp[j] += dp[j - 1];
}
}
}
return dp[n];
}
Explanation: DP where dp[j] = ways to form t[0..j-1] from s[0..i-1]. When chars match, add ways from dp[j-1].
- Time Complexity: O(m×n)
- Space Complexity: O(n)
116. Populating Next Right Pointers in Each Node
Description: Connect each node to its next right node in perfect binary tree.
Java Solution:
public Node connect(Node root) {
if (root == null) return null;
Node leftmost = root;
while (leftmost.left != null) {
Node curr = leftmost;
while (curr != null) {
curr.left.next = curr.right;
if (curr.next != null) {
curr.right.next = curr.next.left;
}
curr = curr.next;
}
leftmost = leftmost.left;
}
return root;
}
Explanation: Use next pointers of current level to connect children. Left child points to right child; right child points to next node’s left child.
- Time Complexity: O(n)
- Space Complexity: O(1)
117. Populating Next Right Pointers in Each Node II
Description: Connect each node to next right node in any binary tree.
Java Solution:
public Node connect(Node root) {
Node curr = root;
while (curr != null) {
Node dummy = new Node(0);
Node tail = dummy;
while (curr != null) {
if (curr.left != null) {
tail.next = curr.left;
tail = tail.next;
}
if (curr.right != null) {
tail.next = curr.right;
tail = tail.next;
}
curr = curr.next;
}
curr = dummy.next;
}
return root;
}
Explanation: Use dummy node to build next level connections. Traverse current level using next pointers, linking all children.
- Time Complexity: O(n)
- Space Complexity: O(1)
118. Pascal’s Triangle
Description: Generate first numRows of Pascal’s triangle.
Java Solution:
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> result = new ArrayList<>();
for (int i = 0; i < numRows; i++) {
List<Integer> row = new ArrayList<>();
for (int j = 0; j <= i; j++) {
if (j == 0 || j == i) {
row.add(1);
} else {
row.add(result.get(i - 1).get(j - 1) + result.get(i - 1).get(j));
}
}
result.add(row);
}
return result;
}
Explanation: Each row starts and ends with 1. Middle elements are sum of two elements above from previous row.
- Time Complexity: O(n²)
- Space Complexity: O(1) excluding output
119. Pascal’s Triangle II
Description: Return the rowIndex-th row of Pascal’s triangle.
Java Solution:
public List<Integer> getRow(int rowIndex) {
List<Integer> row = new ArrayList<>();
row.add(1);
for (int i = 1; i <= rowIndex; i++) {
row.add(0, 1);
for (int j = 1; j < row.size() - 1; j++) {
row.set(j, row.get(j) + row.get(j + 1));
}
}
return row;
}
Explanation: Build row in-place. Add 1 at front, then update middle elements from left to right using values before modification.
- Time Complexity: O(n²)
- Space Complexity: O(1) excluding output
120. Triangle
Description: Find minimum path sum from top to bottom in triangle.
Java Solution:
public int minimumTotal(List<List<Integer>> triangle) {
int n = triangle.size();
int[] dp = new int[n + 1];
for (int i = n - 1; i >= 0; i--) {
for (int j = 0; j <= i; j++) {
dp[j] = triangle.get(i).get(j) + Math.min(dp[j], dp[j + 1]);
}
}
return dp[0];
}
Explanation: Bottom-up DP. At each cell, add current value to minimum of two adjacent cells below. Final answer at dp[0].
- Time Complexity: O(n²)
- Space Complexity: O(n)
121. Best Time to Buy and Sell Stock
Description: Find maximum profit from one buy and one sell transaction.
Java Solution:
public int maxProfit(int[] prices) {
int minPrice = Integer.MAX_VALUE;
int maxProfit = 0;
for (int price : prices) {
minPrice = Math.min(minPrice, price);
maxProfit = Math.max(maxProfit, price - minPrice);
}
return maxProfit;
}
Explanation: Track minimum price seen so far. At each price, calculate potential profit if selling at current price.
- Time Complexity: O(n)
- Space Complexity: O(1)
122. Best Time to Buy and Sell Stock II
Description: Find maximum profit with unlimited transactions.
Java Solution:
public int maxProfit(int[] prices) {
int profit = 0;
for (int i = 1; i < prices.length; i++) {
if (prices[i] > prices[i - 1]) {
profit += prices[i] - prices[i - 1];
}
}
return profit;
}
Explanation: Collect all positive differences (upward movements). Equivalent to buying before every rise and selling at peak.
- Time Complexity: O(n)
- Space Complexity: O(1)
123. Best Time to Buy and Sell Stock III
Description: Find maximum profit with at most two transactions.
Java Solution:
public int maxProfit(int[] prices) {
int buy1 = Integer.MIN_VALUE, sell1 = 0;
int buy2 = Integer.MIN_VALUE, sell2 = 0;
for (int price : prices) {
buy1 = Math.max(buy1, -price);
sell1 = Math.max(sell1, buy1 + price);
buy2 = Math.max(buy2, sell1 - price);
sell2 = Math.max(sell2, buy2 + price);
}
return sell2;
}
Explanation: Track states: first buy, first sell, second buy, second sell. Update each state optimally at every price.
- Time Complexity: O(n)
- Space Complexity: O(1)
124. Binary Tree Maximum Path Sum
Description: Find maximum path sum in binary tree (path can start and end at any node).
Java Solution:
private int maxSum = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
maxGain(root);
return maxSum;
}
private int maxGain(TreeNode node) {
if (node == null) return 0;
int leftGain = Math.max(maxGain(node.left), 0);
int rightGain = Math.max(maxGain(node.right), 0);
maxSum = Math.max(maxSum, node.val + leftGain + rightGain);
return node.val + Math.max(leftGain, rightGain);
}
Explanation: At each node, compute max path through it (left + node + right). Return max single-side path that can extend to parent. Track global maximum.
- Time Complexity: O(n)
- Space Complexity: O(h)
125. Valid Palindrome
Description: Check if string is palindrome considering only alphanumeric characters.
Java Solution:
public boolean isPalindrome(String s) {
int left = 0, right = s.length() - 1;
while (left < right) {
while (left < right && !Character.isLetterOrDigit(s.charAt(left))) left++;
while (left < right && !Character.isLetterOrDigit(s.charAt(right))) right--;
if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) {
return false;
}
left++;
right--;
}
return true;
}
Explanation: Two pointers from both ends, skip non-alphanumeric characters, compare lowercase versions.
- Time Complexity: O(n)
- Space Complexity: O(1)
126. Word Ladder II
Description: Find all shortest transformation sequences from beginWord to endWord.
Java Solution:
public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
List<List<String>> result = new ArrayList<>();
Set<String> dict = new HashSet<>(wordList);
if (!dict.contains(endWord)) return result;
Map<String, List<String>> graph = new HashMap<>();
Map<String, Integer> distance = new HashMap<>();
bfs(beginWord, endWord, dict, graph, distance);
dfs(beginWord, endWord, graph, distance, new ArrayList<>(), result);
return result;
}
private void bfs(String start, String end, Set<String> dict, Map<String, List<String>> graph, Map<String, Integer> distance) {
Queue<String> queue = new LinkedList<>();
queue.offer(start);
distance.put(start, 0);
while (!queue.isEmpty()) {
String word = queue.poll();
List<String> neighbors = getNeighbors(word, dict);
graph.put(word, neighbors);
for (String neighbor : neighbors) {
if (!distance.containsKey(neighbor)) {
distance.put(neighbor, distance.get(word) + 1);
queue.offer(neighbor);
}
}
}
}
private List<String> getNeighbors(String word, Set<String> dict) {
List<String> neighbors = new ArrayList<>();
char[] chars = word.toCharArray();
for (int i = 0; i < chars.length; i++) {
char old = chars[i];
for (char c = 'a'; c <= 'z'; c++) {
chars[i] = c;
String newWord = new String(chars);
if (dict.contains(newWord)) neighbors.add(newWord);
}
chars[i] = old;
}
return neighbors;
}
private void dfs(String curr, String end, Map<String, List<String>> graph, Map<String, Integer> distance, List<String> path, List<List<String>> result) {
path.add(curr);
if (curr.equals(end)) result.add(new ArrayList<>(path));
else if (graph.containsKey(curr)) {
for (String next : graph.get(curr)) {
if (distance.containsKey(next) && distance.get(next) == distance.get(curr) + 1) {
dfs(next, end, graph, distance, path, result);
}
}
}
path.remove(path.size() - 1);
}
Explanation: BFS to build shortest path graph and record distances. DFS to find all paths that follow increasing distances.
- Time Complexity: O(n × m² × 26)
- Space Complexity: O(n × m)
127. Word Ladder
Description: Find length of shortest transformation sequence.
Java Solution:
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
Set<String> dict = new HashSet<>(wordList);
if (!dict.contains(endWord)) return 0;
Queue<String> queue = new LinkedList<>();
queue.offer(beginWord);
int level = 1;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
char[] word = queue.poll().toCharArray();
for (int j = 0; j < word.length; j++) {
char original = word[j];
for (char c = 'a'; c <= 'z'; c++) {
word[j] = c;
String newWord = new String(word);
if (newWord.equals(endWord)) return level + 1;
if (dict.contains(newWord)) {
queue.offer(newWord);
dict.remove(newWord);
}
}
word[j] = original;
}
}
level++;
}
return 0;
}
Explanation: BFS from beginWord. Try all single-character changes, add valid dictionary words to queue. Remove visited words to avoid cycles.
- Time Complexity: O(n × m² × 26)
- Space Complexity: O(n × m)
128. Longest Consecutive Sequence
Description: Find length of longest consecutive sequence in unsorted array.
Java Solution:
public int longestConsecutive(int[] nums) {
Set<Integer> set = new HashSet<>();
for (int num : nums) set.add(num);
int longest = 0;
for (int num : set) {
if (!set.contains(num - 1)) {
int length = 1;
while (set.contains(num + length)) {
length++;
}
longest = Math.max(longest, length);
}
}
return longest;
}
Explanation: Use HashSet for O(1) lookup. Only start counting from sequence start (num-1 not in set). Count consecutive numbers.
- Time Complexity: O(n)
- Space Complexity: O(n)
129. Sum Root to Leaf Numbers
Description: Sum all root-to-leaf numbers formed by paths.
Java Solution:
public int sumNumbers(TreeNode root) {
return dfs(root, 0);
}
private int dfs(TreeNode node, int currentNum) {
if (node == null) return 0;
currentNum = currentNum * 10 + node.val;
if (node.left == null && node.right == null) return currentNum;
return dfs(node.left, currentNum) + dfs(node.right, currentNum);
}
Explanation: DFS passing accumulated number. At each node, multiply by 10 and add current digit. At leaf, return the number.
- Time Complexity: O(n)
- Space Complexity: O(h)
130. Surrounded Regions
Description: Capture surrounded regions by flipping ‘O’ to ‘X’.
Java Solution:
public void solve(char[][] board) {
int m = board.length, n = board[0].length;
for (int i = 0; i < m; i++) {
dfs(board, i, 0);
dfs(board, i, n - 1);
}
for (int j = 0; j < n; j++) {
dfs(board, 0, j);
dfs(board, m - 1, j);
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == 'O') board[i][j] = 'X';
else if (board[i][j] == 'T') board[i][j] = 'O';
}
}
}
private void dfs(char[][] board, int i, int j) {
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != 'O') return;
board[i][j] = 'T';
dfs(board, i + 1, j);
dfs(board, i - 1, j);
dfs(board, i, j + 1);
dfs(board, i, j - 1);
}
Explanation: Mark border-connected ‘O’s as temporary ‘T’. Then flip remaining ‘O’s to ‘X’ and restore ‘T’s to ‘O’.
- Time Complexity: O(m×n)
- Space Complexity: O(m×n) for recursion
131. Palindrome Partitioning
Description: Return all possible palindrome partitionings of string.
Java Solution:
public List<List<String>> partition(String s) {
List<List<String>> result = new ArrayList<>();
backtrack(result, new ArrayList<>(), s, 0);
return result;
}
private void backtrack(List<List<String>> result, List<String> curr, String s, int start) {
if (start == s.length()) {
result.add(new ArrayList<>(curr));
return;
}
for (int end = start + 1; end <= s.length(); end++) {
if (isPalindrome(s, start, end - 1)) {
curr.add(s.substring(start, end));
backtrack(result, curr, s, end);
curr.remove(curr.size() - 1);
}
}
}
private boolean isPalindrome(String s, int left, int right) {
while (left < right) {
if (s.charAt(left++) != s.charAt(right--)) return false;
}
return true;
}
Explanation: Backtracking: try all prefixes that are palindromes, recursively partition the rest.
- Time Complexity: O(n × 2^n)
- Space Complexity: O(n)
132. Palindrome Partitioning II
Description: Find minimum cuts for palindrome partitioning.
Java Solution:
public int minCut(String s) {
int n = s.length();
boolean[][] isPalin = new boolean[n][n];
int[] dp = new int[n];
for (int i = 0; i < n; i++) {
dp[i] = i;
for (int j = 0; j <= i; j++) {
if (s.charAt(j) == s.charAt(i) && (i - j <= 2 || isPalin[j + 1][i - 1])) {
isPalin[j][i] = true;
dp[i] = j == 0 ? 0 : Math.min(dp[i], dp[j - 1] + 1);
}
}
}
return dp[n - 1];
}
Explanation: DP where dp[i] = min cuts for s[0..i]. Precompute palindrome status. If s[j..i] is palindrome, dp[i] = min(dp[i], dp[j-1] + 1).
- Time Complexity: O(n²)
- Space Complexity: O(n²)
133. Clone Graph
Description: Deep copy a graph with nodes and neighbors.
Java Solution:
private Map<Node, Node> visited = new HashMap<>();
public Node cloneGraph(Node node) {
if (node == null) return null;
if (visited.containsKey(node)) return visited.get(node);
Node clone = new Node(node.val);
visited.put(node, clone);
for (Node neighbor : node.neighbors) {
clone.neighbors.add(cloneGraph(neighbor));
}
return clone;
}
Explanation: DFS with hashmap to track visited nodes. Clone current node, recursively clone neighbors, connect clones.
- Time Complexity: O(V + E)
- Space Complexity: O(V)
134. Gas Station
Description: Find starting gas station index for circular route.
Java Solution:
public int canCompleteCircuit(int[] gas, int[] cost) {
int totalTank = 0, currentTank = 0, start = 0;
for (int i = 0; i < gas.length; i++) {
totalTank += gas[i] - cost[i];
currentTank += gas[i] - cost[i];
if (currentTank < 0) {
start = i + 1;
currentTank = 0;
}
}
return totalTank >= 0 ? start : -1;
}
Explanation: If total gas >= total cost, solution exists. Start from position after any point where tank goes negative.
- Time Complexity: O(n)
- Space Complexity: O(1)
135. Candy
Description: Distribute minimum candies to children based on ratings.
Java Solution:
public int candy(int[] ratings) {
int n = ratings.length;
int[] candies = new int[n];
Arrays.fill(candies, 1);
for (int i = 1; i < n; i++) {
if (ratings[i] > ratings[i - 1]) {
candies[i] = candies[i - 1] + 1;
}
}
for (int i = n - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1]) {
candies[i] = Math.max(candies[i], candies[i + 1] + 1);
}
}
int total = 0;
for (int c : candies) total += c;
return total;
}
Explanation: Two passes: left-to-right ensures higher rating than left neighbor gets more candy. Right-to-left does the same for right neighbor.
- Time Complexity: O(n)
- Space Complexity: O(n)
136. Single Number
Description: Find the element that appears only once (others appear twice).
Java Solution:
public int singleNumber(int[] nums) {
int result = 0;
for (int num : nums) {
result ^= num;
}
return result;
}
Explanation: XOR all numbers. Pairs cancel out (a ^ a = 0), leaving only the single number.
- Time Complexity: O(n)
- Space Complexity: O(1)
137. Single Number II
Description: Find the element that appears once (others appear three times).
Java Solution:
public int singleNumber(int[] nums) {
int ones = 0, twos = 0;
for (int num : nums) {
ones = (ones ^ num) & ~twos;
twos = (twos ^ num) & ~ones;
}
return ones;
}
Explanation: Track bits appearing once and twice. When bit appears third time, it’s removed from both. Final ‘ones’ contains the single number.
- Time Complexity: O(n)
- Space Complexity: O(1)
138. Copy List with Random Pointer
Description: Deep copy linked list with random pointers.
Java Solution:
public Node copyRandomList(Node head) {
if (head == null) return null;
Node curr = head;
while (curr != null) {
Node copy = new Node(curr.val);
copy.next = curr.next;
curr.next = copy;
curr = copy.next;
}
curr = head;
while (curr != null) {
if (curr.random != null) {
curr.next.random = curr.random.next;
}
curr = curr.next.next;
}
Node dummy = new Node(0);
Node copyCurr = dummy;
curr = head;
while (curr != null) {
copyCurr.next = curr.next;
curr.next = curr.next.next;
curr = curr.next;
copyCurr = copyCurr.next;
}
return dummy.next;
}
Explanation: Three passes: interleave copies, set random pointers using interleaved structure, separate lists.
- Time Complexity: O(n)
- Space Complexity: O(1)
139. Word Break
Description: Check if string can be segmented into dictionary words.
Java Solution:
public boolean wordBreak(String s, List<String> wordDict) {
Set<String> dict = new HashSet<>(wordDict);
boolean[] dp = new boolean[s.length() + 1];
dp[0] = true;
for (int i = 1; i <= s.length(); i++) {
for (int j = 0; j < i; j++) {
if (dp[j] && dict.contains(s.substring(j, i))) {
dp[i] = true;
break;
}
}
}
return dp[s.length()];
}
Explanation: DP where dp[i] = true if s[0..i-1] can be segmented. Check all possible last words ending at position i.
- Time Complexity: O(n³)
- Space Complexity: O(n)
140. Word Break II
Description: Return all possible sentence segmentations.
Java Solution:
private Map<Integer, List<String>> memo = new HashMap<>();
public List<String> wordBreak(String s, List<String> wordDict) {
Set<String> dict = new HashSet<>(wordDict);
return backtrack(s, 0, dict);
}
private List<String> backtrack(String s, int start, Set<String> dict) {
if (memo.containsKey(start)) return memo.get(start);
List<String> result = new ArrayList<>();
if (start == s.length()) {
result.add("");
return result;
}
for (int end = start + 1; end <= s.length(); end++) {
String word = s.substring(start, end);
if (dict.contains(word)) {
List<String> rest = backtrack(s, end, dict);
for (String sentence : rest) {
result.add(word + (sentence.isEmpty() ? "" : " " + sentence));
}
}
}
memo.put(start, result);
return result;
}
Explanation: Memoized backtracking. For each valid prefix word, recursively get all sentences from remaining string.
- Time Complexity: O(n × 2^n)
- Space Complexity: O(n × 2^n)
141. Linked List Cycle
Description: Detect if linked list has a cycle.
Java Solution:
public boolean hasCycle(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) return true;
}
return false;
}
Explanation: Floyd’s cycle detection: slow pointer moves 1 step, fast moves 2. If cycle exists, they will meet.
- Time Complexity: O(n)
- Space Complexity: O(1)
142. Linked List Cycle II
Description: Find the node where cycle begins.
Java Solution:
public ListNode detectCycle(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
slow = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
return null;
}
Explanation: Floyd’s algorithm: detect cycle, then reset one pointer to head. Move both at same speed; they meet at cycle start. Mathematical proof: distance from head to cycle start equals distance from meeting point to cycle start.
- Time Complexity: O(n)
- Space Complexity: O(1)
143. Reorder List
Description: Reorder list from L0→L1→…→Ln to L0→Ln→L1→Ln-1→…
Java Solution:
public void reorderList(ListNode head) {
if (head == null || head.next == null) return;
// Find middle
ListNode slow = head, fast = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
// Reverse second half
ListNode prev = null, curr = slow.next;
slow.next = null;
while (curr != null) {
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
// Merge two halves
ListNode first = head, second = prev;
while (second != null) {
ListNode tmp1 = first.next, tmp2 = second.next;
first.next = second;
second.next = tmp1;
first = tmp1;
second = tmp2;
}
}
Explanation: Three steps: find middle using slow/fast pointers, reverse second half, merge alternating from both halves.
- Time Complexity: O(n)
- Space Complexity: O(1)
144. Binary Tree Preorder Traversal
Description: Return preorder traversal of binary tree.
Java Solution:
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
if (root != null) stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
result.add(node.val);
if (node.right != null) stack.push(node.right);
if (node.left != null) stack.push(node.left);
}
return result;
}
Explanation: Iterative using stack. Process current, push right then left (so left is processed first). Visit order: root, left, right.
- Time Complexity: O(n)
- Space Complexity: O(n)
145. Binary Tree Postorder Traversal
Description: Return postorder traversal of binary tree.
Java Solution:
public List<Integer> postorderTraversal(TreeNode root) {
LinkedList<Integer> result = new LinkedList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
if (root != null) stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
result.addFirst(node.val);
if (node.left != null) stack.push(node.left);
if (node.right != null) stack.push(node.right);
}
return result;
}
Explanation: Modified preorder (root-right-left) with results added to front, giving left-right-root (postorder).
- Time Complexity: O(n)
- Space Complexity: O(n)
146. LRU Cache
Description: Design LRU cache with O(1) get and put operations.
Java Solution:
class LRUCache {
private int capacity;
private Map<Integer, Node> map;
private Node head, tail;
class Node {
int key, value;
Node prev, next;
Node(int k, int v) { key = k; value = v; }
}
public LRUCache(int capacity) {
this.capacity = capacity;
map = new HashMap<>();
head = new Node(0, 0);
tail = new Node(0, 0);
head.next = tail;
tail.prev = head;
}
public int get(int key) {
if (!map.containsKey(key)) return -1;
Node node = map.get(key);
remove(node);
insertToHead(node);
return node.value;
}
public void put(int key, int value) {
if (map.containsKey(key)) {
Node node = map.get(key);
node.value = value;
remove(node);
insertToHead(node);
} else {
if (map.size() == capacity) {
map.remove(tail.prev.key);
remove(tail.prev);
}
Node node = new Node(key, value);
map.put(key, node);
insertToHead(node);
}
}
private void remove(Node node) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
private void insertToHead(Node node) {
node.next = head.next;
node.prev = head;
head.next.prev = node;
head.next = node;
}
}
Explanation: HashMap for O(1) key lookup, doubly-linked list for O(1) ordering. Most recent at head, least recent at tail.
- Time Complexity: O(1) for both operations
- Space Complexity: O(capacity)
147. Insertion Sort List
Description: Sort linked list using insertion sort.
Java Solution:
public ListNode insertionSortList(ListNode head) {
ListNode dummy = new ListNode(0);
ListNode curr = head;
while (curr != null) {
ListNode prev = dummy;
while (prev.next != null && prev.next.val < curr.val) {
prev = prev.next;
}
ListNode next = curr.next;
curr.next = prev.next;
prev.next = curr;
curr = next;
}
return dummy.next;
}
Explanation: Build sorted list by inserting each node at correct position. Use dummy head for easier insertion handling.
- Time Complexity: O(n²)
- Space Complexity: O(1)
148. Sort List
Description: Sort linked list in O(n log n) time.
Java Solution:
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode slow = head, fast = head.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode mid = slow.next;
slow.next = null;
ListNode left = sortList(head);
ListNode right = sortList(mid);
return merge(left, right);
}
private ListNode merge(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
curr.next = l1;
l1 = l1.next;
} else {
curr.next = l2;
l2 = l2.next;
}
curr = curr.next;
}
curr.next = (l1 != null) ? l1 : l2;
return dummy.next;
}
Explanation: Merge sort: split at middle using slow/fast pointers, recursively sort halves, merge sorted halves.
- Time Complexity: O(n log n)
- Space Complexity: O(log n) for recursion
149. Max Points on a Line
Description: Find maximum points that lie on same line.
Java Solution:
public int maxPoints(int[][] points) {
if (points.length < 3) return points.length;
int maxPoints = 2;
for (int i = 0; i < points.length; i++) {
Map<String, Integer> slopes = new HashMap<>();
int duplicate = 1;
for (int j = i + 1; j < points.length; j++) {
int dx = points[j][0] - points[i][0];
int dy = points[j][1] - points[i][1];
if (dx == 0 && dy == 0) {
duplicate++;
continue;
}
int gcd = gcd(dx, dy);
String slope = (dy / gcd) + "/" + (dx / gcd);
slopes.put(slope, slopes.getOrDefault(slope, 0) + 1);
}
int localMax = duplicate;
for (int count : slopes.values()) {
localMax = Math.max(localMax, count + duplicate);
}
maxPoints = Math.max(maxPoints, localMax);
}
return maxPoints;
}
private int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
Explanation: For each point, calculate slopes to all other points using reduced fractions to avoid floating-point errors. Track max points with same slope.
- Time Complexity: O(n²)
- Space Complexity: O(n)
150. Evaluate Reverse Polish Notation
Description: Evaluate arithmetic expression in Reverse Polish Notation.
Java Solution:
public int evalRPN(String[] tokens) {
Deque<Integer> stack = new ArrayDeque<>();
for (String token : tokens) {
if (token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/")) {
int b = stack.pop();
int a = stack.pop();
switch (token) {
case "+": stack.push(a + b); break;
case "-": stack.push(a - b); break;
case "*": stack.push(a * b); break;
case "/": stack.push(a / b); break;
}
} else {
stack.push(Integer.parseInt(token));
}
}
return stack.pop();
}
Explanation: Stack-based evaluation. Push operands, pop two for operators, push result back. Final stack element is the answer.
- Time Complexity: O(n)
- Space Complexity: O(n)
151. Reverse Words in a String
Description:
Given an input string s, reverse the order of the words. A word is defined as a sequence of non-space characters. The words in s will be separated by at least one space. Return a string of the words in reverse order concatenated by a single space. Note that s may contain leading or trailing spaces or multiple spaces between two words. The returned string should only have a single space separating the words. Do not include any extra spaces.
Java Solution:
public String reverseWords(String s) {
// Trim and split by spaces
String[] words = s.trim().split("\\s+");
// Reverse the array
int left = 0, right = words.length - 1;
while (left < right) {
String temp = words[left];
words[left] = words[right];
words[right] = temp;
left++;
right--;
}
// Join with single space
return String.join(" ", words);
}
Explanation: We first trim the string and split by one or more spaces to get individual words. Then we reverse the array of words in-place using two pointers. Finally, we join the words with a single space. This handles all edge cases including multiple spaces and leading/trailing spaces.
- Time Complexity: O(n) where n is the length of the string
- Space Complexity: O(n) for storing the words array
152. Maximum Product Subarray
Description:
Given an integer array nums, find a contiguous non-empty subarray within the array that has the largest product, and return the product. The test cases are generated so that the answer will fit in a 32-bit integer. A subarray is a contiguous subsequence of the array.
Java Solution:
public int maxProduct(int[] nums) {
if (nums.length == 0) return 0;
int maxSoFar = nums[0];
int maxEndingHere = nums[0];
int minEndingHere = nums[0];
for (int i = 1; i < nums.length; i++) {
int temp = maxEndingHere;
maxEndingHere = Math.max(nums[i], Math.max(maxEndingHere * nums[i], minEndingHere * nums[i]));
minEndingHere = Math.min(nums[i], Math.min(temp * nums[i], minEndingHere * nums[i]));
maxSoFar = Math.max(maxSoFar, maxEndingHere);
}
return maxSoFar;
}
Explanation: This problem is similar to Maximum Subarray but requires tracking both maximum and minimum products at each position. We need the minimum because a negative number times a negative minimum could become a maximum. At each position, we update both max and min by considering: the current number alone, current number times previous max, or current number times previous min.
- Time Complexity: O(n) where n is the length of the array
- Space Complexity: O(1) constant space
153. Find Minimum in Rotated Sorted Array
Description:
Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums = [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2] if it was rotated 4 times. Given the sorted rotated array nums of unique elements, return the minimum element of this array. You must write an algorithm that runs in O(log n) time.
Java Solution:
public int findMin(int[] nums) {
int left = 0, right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
// Right half is unsorted, minimum is in right half
if (nums[mid] > nums[right]) {
left = mid + 1;
} else {
// Left half is unsorted, or minimum is at mid
right = mid;
}
}
return nums[left];
}
Explanation: We use binary search to find the minimum element. The key insight is that in a rotated sorted array, one half is always sorted. If the middle element is greater than the rightmost element, the minimum must be in the right half. Otherwise, the minimum is either at mid or in the left half. We continue narrowing down until left equals right.
- Time Complexity: O(log n) using binary search
- Space Complexity: O(1) constant space
154. Find Minimum in Rotated Sorted Array II
Description:
Suppose an array of length n sorted in ascending order is rotated between 1 and n times. Given the sorted rotated array nums that may contain duplicates, return the minimum element of this array. You must decrease the overall operation steps as much as possible.
Java Solution:
public int findMin(int[] nums) {
int left = 0, right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] > nums[right]) {
left = mid + 1;
} else if (nums[mid] < nums[right]) {
right = mid;
} else {
// nums[mid] == nums[right], can't determine which half
// Skip duplicate from right
right--;
}
}
return nums[left];
}
Explanation: Similar to problem 153, but with duplicates. When middle element equals the rightmost element, we cannot determine which half contains the minimum. In this case, we simply decrement right pointer to skip the duplicate. This handles cases like [1,3,5,1,1,1,1] where duplicates obscure the rotation point.
- Time Complexity: O(log n) average case, O(n) worst case when all elements are the same
- Space Complexity: O(1) constant space
155. Min Stack
Description:
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. Implement the MinStack class with the following methods: push(val) pushes element val onto stack, pop() removes element on top, top() gets top element, and getMin() retrieves the minimum element in the stack. All operations must run in O(1) time.
Java Solution:
class MinStack {
private Stack<Integer> stack;
private Stack<Integer> minStack;
public MinStack() {
stack = new Stack<>();
minStack = new Stack<>();
}
public void push(int val) {
stack.push(val);
if (minStack.isEmpty() || val <= minStack.peek()) {
minStack.push(val);
}
}
public void pop() {
if (stack.pop().equals(minStack.peek())) {
minStack.pop();
}
}
public int top() {
return stack.peek();
}
public int getMin() {
return minStack.peek();
}
}
Explanation: We use two stacks: one for all elements and another to track minimums. When pushing, we add to minStack only if the value is less than or equal to the current minimum. When popping, if the popped value equals the current minimum, we also pop from minStack. This ensures getMin() always returns the current minimum in O(1) time.
- Time Complexity: O(1) for all operations
- Space Complexity: O(n) for the two stacks
156. Binary Tree Upside Down
Description: Given the root of a binary tree, turn the tree upside down and return the new root. You can turn a binary tree upside down with the following steps: The original left child becomes the new root, the original root becomes the new right child, and the original right child becomes the new left child. This process is applied recursively.
Java Solution:
public TreeNode upsideDownBinaryTree(TreeNode root) {
if (root == null || root.left == null) {
return root;
}
TreeNode newRoot = upsideDownBinaryTree(root.left);
root.left.left = root.right;
root.left.right = root;
root.left = null;
root.right = null;
return newRoot;
}
Explanation: We recursively traverse to the leftmost node, which becomes the new root. During backtracking, we rearrange pointers: the current node’s left child gets the current node’s right child as its left, and the current node as its right. We then nullify the current node’s children to prevent cycles. This effectively flips the tree upside down.
- Time Complexity: O(n) where n is the number of nodes
- Space Complexity: O(h) for recursion stack, where h is height
157. Read N Characters Given Read4
Description:
Given a file and assume that you can only read the file using a given method read4 which reads 4 characters at a time. Implement a method read to read n characters. Your method read may be called multiple times. The method read4 reads up to 4 consecutive characters from file and writes them into the buffer array buf4. The return value is the actual number of characters read.
Java Solution:
public class Solution extends Reader4 {
public int read(char[] buf, int n) {
int total = 0;
char[] temp = new char[4];
while (total < n) {
int count = read4(temp);
// Copy characters from temp to buf
for (int i = 0; i < count && total < n; i++) {
buf[total++] = temp[i];
}
// If read4 returns less than 4, we've reached EOF
if (count < 4) {
break;
}
}
return total;
}
}
Explanation: We repeatedly call read4 to fill a temporary buffer of size 4, then copy characters to the output buffer until we’ve read n characters or reached end of file. The key is to track the total characters read and stop when we reach n or when read4 returns fewer than 4 characters (indicating EOF).
- Time Complexity: O(n) where n is the number of characters to read
- Space Complexity: O(1) using a fixed-size temporary buffer
158. Read N Characters Given Read4 II - Call Multiple Times
Description:
Similar to problem 157, but the read method may be called multiple times. You need to maintain state between calls to handle leftover characters from previous read4 calls. This is more complex because you might read more than needed in one call and need to save those characters for the next call.
Java Solution:
public class Solution extends Reader4 {
private char[] buffer = new char[4];
private int bufferIndex = 0;
private int bufferCount = 0;
public int read(char[] buf, int n) {
int total = 0;
while (total < n) {
// If buffer is empty, read from file
if (bufferIndex == bufferCount) {
bufferCount = read4(buffer);
bufferIndex = 0;
if (bufferCount == 0) break; // EOF
}
// Copy from buffer to buf
while (total < n && bufferIndex < bufferCount) {
buf[total++] = buffer[bufferIndex++];
}
}
return total;
}
}
Explanation: We maintain a buffer and pointers between calls. When buffer is exhausted, we call read4 to refill it. We copy characters from our buffer to the output buffer until we’ve read n characters or reached EOF. This preserves state across multiple read calls, handling leftover characters correctly.
- Time Complexity: O(n) for reading n characters
- Space Complexity: O(1) with fixed-size buffer of 4
159. Longest Substring with At Most Two Distinct Characters
Description:
Given a string s, return the length of the longest substring that contains at most two distinct characters. This is a sliding window problem where you need to find the maximum window size while maintaining the constraint.
Java Solution:
public int lengthOfLongestSubstringTwoDistinct(String s) {
if (s.length() < 3) return s.length();
Map<Character, Integer> map = new HashMap<>();
int left = 0, maxLen = 0;
for (int right = 0; right < s.length(); right++) {
map.put(s.charAt(right), right);
// If we have more than 2 distinct characters
if (map.size() > 2) {
// Find the leftmost character
int leftmost = Collections.min(map.values());
map.remove(s.charAt(leftmost));
left = leftmost + 1;
}
maxLen = Math.max(maxLen, right - left + 1);
}
return maxLen;
}
Explanation: We use a sliding window with a hashmap that stores characters and their rightmost indices. When we have more than 2 distinct characters, we remove the character with the smallest index (leftmost) and move the left pointer. We track the maximum window size throughout.
- Time Complexity: O(n) where n is the length of the string
- Space Complexity: O(1) since map has at most 3 entries
160. Intersection of Two Linked Lists
Description:
Given the heads of two singly linked lists headA and headB, return the node at which the two lists intersect. If the two linked lists have no intersection at all, return null. The linked lists must retain their original structure after the function returns.
Java Solution:
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
ListNode a = headA;
ListNode b = headB;
// If they intersect, they will meet before both become null
// If not, both will become null at the same time
while (a != b) {
a = (a == null) ? headB : a.next;
b = (b == null) ? headA : b.next;
}
return a;
}
Explanation: The elegant two-pointer solution works by having each pointer traverse both lists. When pointer A reaches the end of list A, it continues at the head of list B, and vice versa. If the lists intersect, the pointers will meet at the intersection. If not, both will become null at the same time. This equalizes the path lengths.
- Time Complexity: O(m + n) where m and n are the lengths of the two lists
- Space Complexity: O(1) constant space
161. One Edit Distance
Description:
Given two strings s and t, return true if they are both one edit distance apart, otherwise return false. A string s is one distance apart from a string t if exactly one of the following is true: Insert a character into s to get t, delete a character from s to get t, or replace a character of s to get t.
Java Solution:
public boolean isOneEditDistance(String s, String t) {
int m = s.length(), n = t.length();
// Ensure s is shorter for simplicity
if (m > n) return isOneEditDistance(t, s);
// Length difference must be 0 or 1
if (n - m > 1) return false;
for (int i = 0; i < m; i++) {
if (s.charAt(i) != t.charAt(i)) {
if (m == n) {
// Replace: check if rest is same
return s.substring(i + 1).equals(t.substring(i + 1));
} else {
// Insert: check if s[i:] equals t[i+1:]
return s.substring(i).equals(t.substring(i + 1));
}
}
}
// All characters match, only valid if lengths differ by 1
return n - m == 1;
}
Explanation: We compare characters from both strings. When we find a mismatch, we check if the rest matches after performing the appropriate edit (replace or insert). If all characters match, the strings must differ by exactly one character in length to be one edit distance apart.
- Time Complexity: O(n) where n is the length of the shorter string
- Space Complexity: O(n) for substring operations
162. Find Peak Element
Description:
A peak element is an element that is strictly greater than its neighbors. Given a 0-indexed integer array nums, find a peak element, and return its index. If the array contains multiple peaks, return the index to any of the peaks. You may imagine that nums[-1] = nums[n] = -∞. You must write an algorithm that runs in O(log n) time.
Java Solution:
public int findPeakElement(int[] nums) {
int left = 0, right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] > nums[mid + 1]) {
// Peak is on the left side (or mid is peak)
right = mid;
} else {
// Peak is on the right side
left = mid + 1;
}
}
return left;
}
Explanation: We use binary search to find a peak. At each step, we compare the middle element with its right neighbor. If mid is greater than mid+1, a peak must exist on the left side (or mid itself is a peak). Otherwise, a peak must exist on the right side. We continue until left equals right, which will be a peak index.
- Time Complexity: O(log n) using binary search
- Space Complexity: O(1) constant space
163. Missing Ranges
Description:
You are given an inclusive range [lower, upper] and a sorted unique integer array nums, where all elements are within the inclusive range. A number x is considered missing if x is in the range [lower, upper] and x is not in nums. Return the smallest sorted list of ranges that cover all the missing numbers exactly.
Java Solution:
public List<String> findMissingRanges(int[] nums, int lower, int upper) {
List<String> result = new ArrayList<>();
long next = lower; // Use long to avoid overflow
for (int num : nums) {
if (num < next) continue;
if (num == next) {
next++;
continue;
}
result.add(getRange(next, num - 1));
next = (long) num + 1;
}
if (next <= upper) {
result.add(getRange(next, upper));
}
return result;
}
private String getRange(long start, long end) {
return (start == end) ? String.valueOf(start) : start + "->" + end;
}
Explanation: We iterate through the array, tracking the next expected number. When there’s a gap between the expected number and current number, we add the missing range. After processing all numbers, we check if there’s a missing range to the upper bound. We handle single numbers and ranges differently in the output format.
- Time Complexity: O(n) where n is the length of nums
- Space Complexity: O(1) excluding the output list
164. Maximum Gap
Description:
Given an integer array nums, return the maximum difference between two successive elements in its sorted form. If the array contains less than two elements, return 0. You must write an algorithm that runs in linear time and uses linear extra space.
Java Solution:
public int maximumGap(int[] nums) {
if (nums.length < 2) return 0;
int n = nums.length;
int min = nums[0], max = nums[0];
for (int num : nums) {
min = Math.min(min, num);
max = Math.max(max, num);
}
// Bucket size (ceiling division)
int bucketSize = Math.max(1, (max - min) / (n - 1));
int bucketCount = (max - min) / bucketSize + 1;
int[] bucketMin = new int[bucketCount];
int[] bucketMax = new int[bucketCount];
Arrays.fill(bucketMin, Integer.MAX_VALUE);
Arrays.fill(bucketMax, Integer.MIN_VALUE);
for (int num : nums) {
int idx = (num - min) / bucketSize;
bucketMin[idx] = Math.min(bucketMin[idx], num);
bucketMax[idx] = Math.max(bucketMax[idx], num);
}
int maxGap = 0, prev = min;
for (int i = 0; i < bucketCount; i++) {
if (bucketMin[i] == Integer.MAX_VALUE) continue;
maxGap = Math.max(maxGap, bucketMin[i] - prev);
prev = bucketMax[i];
}
return maxGap;
}
Explanation: We use the pigeonhole principle with bucket sort. The maximum gap must be at least the average gap, so gaps within buckets can be ignored. We place numbers into buckets and track min/max per bucket. The maximum gap is found between consecutive non-empty buckets.
- Time Complexity: O(n) linear time using bucket sort concept
- Space Complexity: O(n) for bucket arrays
165. Compare Version Numbers
Description:
Given two version numbers, version1 and version2, compare them. Version numbers consist of one or more revisions joined by a dot ’.’. Each revision consists of digits and may contain leading zeros. Return -1 if version1 < version2, return 1 if version1 > version2, otherwise return 0.
Java Solution:
public int compareVersion(String version1, String version2) {
String[] v1 = version1.split("\\.");
String[] v2 = version2.split("\\.");
int maxLen = Math.max(v1.length, v2.length);
for (int i = 0; i < maxLen; i++) {
int num1 = i < v1.length ? Integer.parseInt(v1[i]) : 0;
int num2 = i < v2.length ? Integer.parseInt(v2[i]) : 0;
if (num1 < num2) {
return -1;
} else if (num1 > num2) {
return 1;
}
}
return 0;
}
Explanation: We split both version strings by dots and compare corresponding revisions as integers. This automatically handles leading zeros. If one version is shorter, we treat missing revisions as 0. We iterate through all revisions and return the comparison result as soon as we find a difference.
- Time Complexity: O(n + m) where n and m are the lengths of version strings
- Space Complexity: O(n + m) for split arrays
166. Fraction to Recurring Decimal
Description: Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. If the fractional part is repeating, enclose the repeating part in parentheses. If multiple answers are possible, return any of them. It is guaranteed that the length of the answer string is less than 10^4 for all the given inputs.
Java Solution:
public String fractionToDecimal(int numerator, int denominator) {
if (numerator == 0) return "0";
StringBuilder result = new StringBuilder();
if ((numerator < 0) ^ (denominator < 0)) {
result.append("-");
}
long num = Math.abs((long) numerator);
long den = Math.abs((long) denominator);
result.append(num / den);
long remainder = num % den;
if (remainder == 0) return result.toString();
result.append(".");
Map<Long, Integer> map = new HashMap<>();
while (remainder != 0) {
if (map.containsKey(remainder)) {
result.insert(map.get(remainder), "(");
result.append(")");
break;
}
map.put(remainder, result.length());
remainder *= 10;
result.append(remainder / den);
remainder %= den;
}
return result.toString();
}
Explanation: We handle sign separately, then compute integer part and remainder. For the decimal part, we track remainders in a map with their positions. When we see a remainder we’ve seen before, we’ve found the repeating cycle and insert parentheses. We use long to avoid overflow.
- Time Complexity: O(d) where d is the length of the result
- Space Complexity: O(d) for the map and result string
167. Two Sum II - Input Array Is Sorted
Description:
Given a 1-indexed array of integers numbers that is already sorted in non-decreasing order, find two numbers such that they add up to a specific target number. Return the indices of the two numbers, index1 and index2, added by one. You may not use the same element twice. Your solution must use only constant extra space.
Java Solution:
public int[] twoSum(int[] numbers, int target) {
int left = 0, right = numbers.length - 1;
while (left < right) {
int sum = numbers[left] + numbers[right];
if (sum == target) {
return new int[]{left + 1, right + 1}; // 1-indexed
} else if (sum < target) {
left++;
} else {
right--;
}
}
return new int[]{-1, -1}; // Should never reach here
}
Explanation: Since the array is sorted, we use a two-pointer approach. Start with pointers at both ends. If the sum is too small, move left pointer right to increase sum. If too large, move right pointer left to decrease sum. When we find the target, return the 1-indexed positions.
- Time Complexity: O(n) where n is the length of the array
- Space Complexity: O(1) constant extra space
168. Excel Sheet Column Title
Description:
Given an integer columnNumber, return its corresponding column title as it appears in an Excel sheet. For example: A -> 1, B -> 2, C -> 3, …, Z -> 26, AA -> 27, AB -> 28, etc. This is essentially a base-26 number system but with a twist: there’s no zero.
Java Solution:
public String convertToTitle(int columnNumber) {
StringBuilder result = new StringBuilder();
while (columnNumber > 0) {
columnNumber--; // Adjust for 1-based indexing
int remainder = columnNumber % 26;
result.append((char) ('A' + remainder));
columnNumber /= 26;
}
return result.reverse().toString();
}
Explanation: This is similar to base conversion but Excel columns are 1-indexed (A=1, not A=0). We decrement the number first to handle this. Then we get the remainder (0-25) which maps to A-Z, append the character, and continue with the quotient. Finally, reverse the result since we built it backwards.
- Time Complexity: O(log n) where n is the column number (base 26)
- Space Complexity: O(log n) for the result string
169. Majority Element
Description:
Given an array nums of size n, return the majority element. The majority element is the element that appears more than ⌊n / 2⌋ times. You may assume that the majority element always exists in the array. Follow-up: Could you solve the problem in linear time and O(1) space?
Java Solution:
public int majorityElement(int[] nums) {
int candidate = nums[0];
int count = 1;
// Boyer-Moore Voting Algorithm
for (int i = 1; i < nums.length; i++) {
if (count == 0) {
candidate = nums[i];
count = 1;
} else if (nums[i] == candidate) {
count++;
} else {
count--;
}
}
return candidate;
}
Explanation: We use the Boyer-Moore Voting Algorithm. The idea is to maintain a candidate and a count. When count is 0, we pick a new candidate. If we see the candidate, increment count; otherwise decrement. Since the majority element appears more than n/2 times, it will always be the final candidate after all pairs of different elements cancel out.
- Time Complexity: O(n) single pass through the array
- Space Complexity: O(1) constant space
170. Two Sum III - Data Structure Design
Description:
Design a data structure that accepts a stream of integers and checks if it has a pair of integers that sum up to a particular value. Implement the TwoSum class: add(number) adds number to the data structure, and find(value) returns true if there exists any pair of numbers whose sum is equal to value.
Java Solution:
class TwoSum {
private Map<Integer, Integer> map;
public TwoSum() {
map = new HashMap<>();
}
public void add(int number) {
map.put(number, map.getOrDefault(number, 0) + 1);
}
public boolean find(int value) {
for (int num : map.keySet()) {
int complement = value - num;
if (complement == num) {
// Same number, need at least 2 occurrences
if (map.get(num) > 1) return true;
} else {
if (map.containsKey(complement)) return true;
}
}
return false;
}
}
Explanation: We use a HashMap to store numbers with their frequencies. When adding, we increment the count. When finding, we check each number’s complement. If the complement equals the number itself, we need at least 2 occurrences. Otherwise, we just check if the complement exists in the map.
- Time Complexity: add() is O(1), find() is O(n) where n is unique numbers
- Space Complexity: O(n) for storing the numbers
171. Excel Sheet Column Number
Description:
Given a string columnTitle that represents the column title as appears in an Excel sheet, return its corresponding column number. For example: A -> 1, B -> 2, C -> 3, …, Z -> 26, AA -> 27, AB -> 28, etc. This is the reverse of problem 168.
Java Solution:
public int titleToNumber(String columnTitle) {
int result = 0;
for (int i = 0; i < columnTitle.length(); i++) {
int digit = columnTitle.charAt(i) - 'A' + 1;
result = result * 26 + digit;
}
return result;
}
Explanation: This is a base-26 to decimal conversion. We process each character from left to right, treating it as a digit in base-26. For each character, we multiply the current result by 26 (shift left in base-26) and add the value of the current character (A=1, B=2, …, Z=26). This is similar to converting binary to decimal but with base 26.
- Time Complexity: O(n) where n is the length of the column title
- Space Complexity: O(1) constant space
172. Factorial Trailing Zeroes
Description:
Given an integer n, return the number of trailing zeroes in n!. Note that n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1. Follow-up: Could you write a solution that works in logarithmic time complexity?
Java Solution:
public int trailingZeroes(int n) {
int count = 0;
while (n > 0) {
n /= 5;
count += n;
}
return count;
}
Explanation: Trailing zeros are created by factors of 10, which is 2 × 5. In factorials, there are always more factors of 2 than 5, so we only need to count factors of 5. Numbers divisible by 5 contribute one factor of 5, numbers divisible by 25 contribute an additional factor, etc. We divide n by 5 repeatedly and sum up the quotients to get the total count of factors of 5.
- Time Complexity: O(log n) logarithmic in base 5
- Space Complexity: O(1) constant space
173. Binary Search Tree Iterator
Description:
Implement the BSTIterator class that represents an iterator over the in-order traversal of a binary search tree (BST). The class has methods: next() returns the next smallest number in the BST, and hasNext() returns whether we have a next smallest number. You must implement both methods in average O(1) time and use O(h) memory, where h is the height of the tree.
Java Solution:
class BSTIterator {
private Stack<TreeNode> stack;
public BSTIterator(TreeNode root) {
stack = new Stack<>();
pushLeft(root);
}
public int next() {
TreeNode node = stack.pop();
if (node.right != null) {
pushLeft(node.right);
}
return node.val;
}
public boolean hasNext() {
return !stack.isEmpty();
}
private void pushLeft(TreeNode node) {
while (node != null) {
stack.push(node);
node = node.left;
}
}
}
Explanation: We use a stack to simulate in-order traversal iteratively. Initially, we push all left nodes from root. For next(), we pop a node, and if it has a right child, we push all left nodes from that right child. This ensures we always have the next smallest element at the top of the stack. Each node is pushed and popped exactly once, giving amortized O(1) time.
- Time Complexity: O(1) average for both operations, O(n) total for all calls
- Space Complexity: O(h) where h is the tree height
174. Dungeon Game
Description: The demons had captured the princess and imprisoned her in the bottom-right corner of a dungeon. The knight starts in the top-left corner and must reach the princess. Each room has a value that either gives health (positive) or takes health (negative). Determine the knight’s minimum initial health so that he can rescue the princess. The knight’s health must never drop to 0 or below.
Java Solution:
public int calculateMinimumHP(int[][] dungeon) {
int m = dungeon.length, n = dungeon[0].length;
int[][] dp = new int[m][n];
// Start from bottom-right
dp[m - 1][n - 1] = Math.max(1, 1 - dungeon[m - 1][n - 1]);
// Fill last column
for (int i = m - 2; i >= 0; i--) {
dp[i][n - 1] = Math.max(1, dp[i + 1][n - 1] - dungeon[i][n - 1]);
}
// Fill last row
for (int j = n - 2; j >= 0; j--) {
dp[m - 1][j] = Math.max(1, dp[m - 1][j + 1] - dungeon[m - 1][j]);
}
// Fill rest of the table
for (int i = m - 2; i >= 0; i--) {
for (int j = n - 2; j >= 0; j--) {
int minHealth = Math.min(dp[i + 1][j], dp[i][j + 1]);
dp[i][j] = Math.max(1, minHealth - dungeon[i][j]);
}
}
return dp[0][0];
}
Explanation: We use dynamic programming from bottom-right to top-left. dp[i][j] represents minimum health needed at position (i,j) to reach the princess. At each cell, we need enough health to survive the current cell and reach the next cell with minimum required health. The answer ensures health never drops below 1.
- Time Complexity: O(m × n) where m and n are dimensions
- Space Complexity: O(m × n) for the DP table
175. Combine Two Tables
Description: Write a SQL query to report the first name, last name, city, and state of each person in the Person table. If the address of a personId is not present in the Address table, report null instead. This is a database problem testing SQL LEFT JOIN.
Java Solution:
// This is a SQL problem, not a Java problem
// SQL Solution:
/*
SELECT
p.firstName,
p.lastName,
a.city,
a.state
FROM
Person p
LEFT JOIN
Address a
ON
p.personId = a.personId;
*/
// For demonstration purposes, here's how you might solve it in Java:
public class Solution {
public List<PersonAddress> combinePersonAddress(
List<Person> persons, List<Address> addresses) {
Map<Integer, Address> addressMap = new HashMap<>();
for (Address addr : addresses) {
addressMap.put(addr.personId, addr);
}
List<PersonAddress> result = new ArrayList<>();
for (Person person : persons) {
Address addr = addressMap.get(person.personId);
result.add(new PersonAddress(
person.firstName,
person.lastName,
addr != null ? addr.city : null,
addr != null ? addr.state : null
));
}
return result;
}
}
Explanation: This is primarily a SQL problem requiring a LEFT JOIN to combine Person and Address tables. In Java, we simulate this by creating a map of personId to Address, then iterate through persons and look up their addresses. If no address exists, we use null values.
- Time Complexity: O(n + m) where n is persons and m is addresses
- Space Complexity: O(m) for the address map
176. Second Highest Salary
Description: Write a SQL query to report the second highest salary from the Employee table. If there is no second highest salary, the query should report null. This tests your understanding of SQL aggregation and handling edge cases.
Java Solution:
// This is a SQL problem, not a Java problem
// SQL Solution:
/*
SELECT MAX(salary) AS SecondHighestSalary
FROM Employee
WHERE salary < (SELECT MAX(salary) FROM Employee);
*/
// Alternative SQL using LIMIT and OFFSET:
/*
SELECT
(SELECT DISTINCT salary
FROM Employee
ORDER BY salary DESC
LIMIT 1 OFFSET 1) AS SecondHighestSalary;
*/
// For demonstration, here's a Java implementation:
public Integer findSecondHighestSalary(List<Integer> salaries) {
if (salaries.isEmpty()) return null;
Set<Integer> uniqueSalaries = new TreeSet<>(Collections.reverseOrder());
uniqueSalaries.addAll(salaries);
if (uniqueSalaries.size() < 2) return null;
Iterator<Integer> iterator = uniqueSalaries.iterator();
iterator.next(); // Skip first (highest)
return iterator.next(); // Return second
}
Explanation: The SQL approach finds the maximum salary that is less than the overall maximum. Alternatively, we can use DISTINCT with ORDER BY and OFFSET. In Java, we use a TreeSet in descending order to maintain unique salaries sorted, then return the second element if it exists.
- Time Complexity: O(n log n) for sorting unique salaries
- Space Complexity: O(n) for storing unique salaries
177. Nth Highest Salary
Description: Write a SQL query to report the nth highest salary from the Employee table. If there is no nth highest salary, the query should report null. This is a generalization of problem 176, requiring dynamic offset handling.
Java Solution:
// This is a SQL problem, not a Java problem
// SQL Solution (MySQL):
/*
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
DECLARE M INT;
SET M = N - 1;
RETURN (
SELECT DISTINCT salary
FROM Employee
ORDER BY salary DESC
LIMIT 1 OFFSET M
);
END
*/
// For demonstration, here's a Java implementation:
public Integer findNthHighestSalary(List<Integer> salaries, int n) {
if (n <= 0 || salaries.isEmpty()) return null;
// Use TreeSet to maintain unique salaries in descending order
Set<Integer> uniqueSalaries = new TreeSet<>(Collections.reverseOrder());
uniqueSalaries.addAll(salaries);
if (uniqueSalaries.size() < n) return null;
// Get the nth element
Iterator<Integer> iterator = uniqueSalaries.iterator();
for (int i = 1; i < n; i++) {
iterator.next();
}
return iterator.next();
}
Explanation: The SQL solution uses LIMIT with OFFSET to get the nth highest salary after sorting distinct salaries in descending order. In Java, we use a TreeSet with reverse order to maintain unique sorted salaries, then iterate to the nth position. We handle edge cases where n is invalid or there aren’t enough unique salaries.
- Time Complexity: O(n log n) for sorting unique salaries
- Space Complexity: O(k) where k is the number of unique salaries
178. Rank Scores
Description: Write a SQL query to rank the scores in the Scores table. The scores should be ranked from highest to lowest. If there is a tie between two scores, both should have the same ranking. Note that after a tie, the next ranking number should be the next consecutive integer value (dense ranking).
Java Solution:
// This is a SQL problem, not a Java problem
// SQL Solution:
/*
SELECT
score,
DENSE_RANK() OVER (ORDER BY score DESC) AS 'rank'
FROM
Scores;
*/
// Alternative without window functions:
/*
SELECT
s1.score,
(SELECT COUNT(DISTINCT s2.score)
FROM Scores s2
WHERE s2.score >= s1.score) AS 'rank'
FROM
Scores s1
ORDER BY
s1.score DESC;
*/
// For demonstration, here's a Java implementation:
public List<ScoreRank> rankScores(List<Double> scores) {
List<Double> sortedUnique = new ArrayList<>(new TreeSet<>(scores));
Collections.sort(sortedUnique, Collections.reverseOrder());
Map<Double, Integer> rankMap = new HashMap<>();
for (int i = 0; i < sortedUnique.size(); i++) {
rankMap.put(sortedUnique.get(i), i + 1);
}
List<ScoreRank> result = new ArrayList<>();
for (Double score : scores) {
result.add(new ScoreRank(score, rankMap.get(score)));
}
return result;
}
Explanation: The SQL solution uses DENSE_RANK() window function to assign ranks. In Java, we first get unique sorted scores, create a rank mapping, then assign ranks to all original scores. Dense ranking ensures consecutive rank numbers even with ties.
- Time Complexity: O(n log n) for sorting
- Space Complexity: O(n) for storing unique scores and ranks
179. Largest Number
Description:
Given a list of non-negative integers nums, arrange them such that they form the largest number and return it. Since the result may be very large, you need to return a string instead of an integer. For example, given [3,30,34,5,9], the largest formed number is “9534330”.
Java Solution:
public String largestNumber(int[] nums) {
String[] strs = new String[nums.length];
for (int i = 0; i < nums.length; i++) {
strs[i] = String.valueOf(nums[i]);
}
// Custom comparator: compare concatenated results
Arrays.sort(strs, (a, b) -> (b + a).compareTo(a + b));
// Edge case: if largest number is "0", return "0"
if (strs[0].equals("0")) {
return "0";
}
StringBuilder result = new StringBuilder();
for (String str : strs) {
result.append(str);
}
return result.toString();
}
Explanation: We convert numbers to strings and sort them with a custom comparator. For two strings a and b, we compare ab vs ba to determine which should come first. For example, “3” and “30”: “330” vs “303”, so “3” comes first. After sorting, we concatenate all strings. We handle the edge case where all numbers are 0.
- Time Complexity: O(n log n) for sorting, where comparison is O(k) with k being average digit length
- Space Complexity: O(n) for string array
180. Consecutive Numbers
Description: Write a SQL query to find all numbers that appear at least three times consecutively in the Logs table. The Logs table has columns id and num. Return the result in any order. This tests your understanding of self-joins and consecutive row comparison.
Java Solution:
// This is a SQL problem, not a Java problem
// SQL Solution:
/*
SELECT DISTINCT l1.num AS ConsecutiveNums
FROM Logs l1
JOIN Logs l2 ON l1.id = l2.id - 1
JOIN Logs l3 ON l1.id = l3.id - 2
WHERE l1.num = l2.num AND l2.num = l3.num;
*/
// Alternative using window functions:
/*
SELECT DISTINCT num AS ConsecutiveNums
FROM (
SELECT num,
LEAD(num, 1) OVER (ORDER BY id) AS next1,
LEAD(num, 2) OVER (ORDER BY id) AS next2
FROM Logs
) AS temp
WHERE num = next1 AND num = next2;
*/
// For demonstration, here's a Java implementation:
public List<Integer> findConsecutiveNumbers(List<LogEntry> logs) {
Set<Integer> result = new HashSet<>();
for (int i = 0; i < logs.size() - 2; i++) {
if (logs.get(i).num == logs.get(i + 1).num &&
logs.get(i).num == logs.get(i + 2).num) {
result.add(logs.get(i).num);
}
}
return new ArrayList<>(result);
}
Explanation: The SQL approach uses self-joins to compare three consecutive rows, or window functions like LEAD to access following rows. In Java, we simply iterate through the list and check if three consecutive entries have the same number, collecting unique results in a set.
- Time Complexity: O(n) where n is the number of log entries
- Space Complexity: O(k) where k is the number of unique consecutive numbers
181. Employees Earning More Than Their Managers
Description: Write a SQL query to find the employees who earn more than their managers. The Employee table has columns id, name, salary, and managerId. Return the result containing the name of employees who earn more than their managers.
Java Solution:
// This is a SQL problem, not a Java problem
// SQL Solution:
/*
SELECT e1.name AS Employee
FROM Employee e1
JOIN Employee e2
ON e1.managerId = e2.id
WHERE e1.salary > e2.salary;
*/
// For demonstration, here's a Java implementation:
public List<String> findEmployeesEarningMore(List<Employee> employees) {
Map<Integer, Employee> empMap = new HashMap<>();
for (Employee emp : employees) {
empMap.put(emp.id, emp);
}
List<String> result = new ArrayList<>();
for (Employee emp : employees) {
if (emp.managerId != null) {
Employee manager = empMap.get(emp.managerId);
if (manager != null && emp.salary > manager.salary) {
result.add(emp.name);
}
}
}
return result;
}
class Employee {
int id;
String name;
int salary;
Integer managerId;
}
Explanation: The SQL solution uses a self-join to compare each employee with their manager based on managerId. In Java, we create a map of employees by id for quick lookup, then iterate through employees comparing their salary with their manager’s salary. We collect names of employees who earn more.
- Time Complexity: O(n) where n is the number of employees
- Space Complexity: O(n) for the employee map
182. Duplicate Emails
Description: Write a SQL query to report all the duplicate emails in the Person table. The Person table has columns id and email. Note that it’s guaranteed that the email field is not NULL. Return the result in any order.
Java Solution:
// This is a SQL problem, not a Java problem
// SQL Solution:
/*
SELECT email AS Email
FROM Person
GROUP BY email
HAVING COUNT(*) > 1;
*/
// Alternative using subquery:
/*
SELECT DISTINCT p1.email AS Email
FROM Person p1
JOIN Person p2
ON p1.email = p2.email AND p1.id != p2.id;
*/
// For demonstration, here's a Java implementation:
public List<String> findDuplicateEmails(List<String> emails) {
Map<String, Integer> emailCount = new HashMap<>();
for (String email : emails) {
emailCount.put(email, emailCount.getOrDefault(email, 0) + 1);
}
List<String> duplicates = new ArrayList<>();
for (Map.Entry<String, Integer> entry : emailCount.entrySet()) {
if (entry.getValue() > 1) {
duplicates.add(entry.getKey());
}
}
return duplicates;
}
Explanation: The SQL solution uses GROUP BY with HAVING to find emails that appear more than once. In Java, we count email occurrences using a HashMap, then filter for emails with count greater than 1. Both approaches efficiently identify duplicates.
- Time Complexity: O(n) where n is the number of emails
- Space Complexity: O(k) where k is the number of unique emails
183. Customers Who Never Order
Description: Write a SQL query to report all customers who never order anything. The Customers table has columns id and name. The Orders table has columns id and customerId. Find all customer names who don’t have any corresponding orders.
Java Solution:
// This is a SQL problem, not a Java problem
// SQL Solution:
/*
SELECT name AS Customers
FROM Customers
WHERE id NOT IN (
SELECT customerId
FROM Orders
);
*/
// Alternative using LEFT JOIN:
/*
SELECT c.name AS Customers
FROM Customers c
LEFT JOIN Orders o
ON c.id = o.customerId
WHERE o.id IS NULL;
*/
// For demonstration, here's a Java implementation:
public List<String> findCustomersWithoutOrders(
List<Customer> customers, List<Order> orders) {
Set<Integer> customerIdsWithOrders = new HashSet<>();
for (Order order : orders) {
customerIdsWithOrders.add(order.customerId);
}
List<String> result = new ArrayList<>();
for (Customer customer : customers) {
if (!customerIdsWithOrders.contains(customer.id)) {
result.add(customer.name);
}
}
return result;
}
class Customer {
int id;
String name;
}
class Order {
int id;
int customerId;
}
Explanation: The SQL solution uses NOT IN to find customers whose id doesn’t appear in the Orders table, or uses LEFT JOIN to find customers with no matching orders. In Java, we collect all customer IDs that have orders in a set, then filter customers not in this set.
- Time Complexity: O(n + m) where n is customers and m is orders
- Space Complexity: O(m) for storing customer IDs with orders
184. Department Highest Salary
Description: Write a SQL query to find employees who have the highest salary in each department. The Employee table has columns id, name, salary, and departmentId. The Department table has columns id and name. Return the department name, employee name, and salary for employees with the highest salary in their department.
Java Solution:
// This is a SQL problem, not a Java problem
// SQL Solution:
/*
SELECT d.name AS Department,
e.name AS Employee,
e.salary AS Salary
FROM Employee e
JOIN Department d ON e.departmentId = d.id
WHERE (e.departmentId, e.salary) IN (
SELECT departmentId, MAX(salary)
FROM Employee
GROUP BY departmentId
);
*/
// For demonstration, here's a Java implementation:
public List<DepartmentHighest> findHighestSalaries(
List<Employee> employees, List<Department> departments) {
// Find max salary per department
Map<Integer, Integer> maxSalaryByDept = new HashMap<>();
for (Employee emp : employees) {
maxSalaryByDept.put(emp.departmentId,
Math.max(maxSalaryByDept.getOrDefault(emp.departmentId, 0),
emp.salary));
}
// Create department name map
Map<Integer, String> deptNames = new HashMap<>();
for (Department dept : departments) {
deptNames.put(dept.id, dept.name);
}
// Find employees with max salary in their department
List<DepartmentHighest> result = new ArrayList<>();
for (Employee emp : employees) {
if (emp.salary == maxSalaryByDept.get(emp.departmentId)) {
result.add(new DepartmentHighest(
deptNames.get(emp.departmentId),
emp.name,
emp.salary
));
}
}
return result;
}
Explanation: The SQL solution uses a subquery to find the maximum salary per department, then joins to get matching employees. In Java, we first compute max salary per department, then filter employees matching this maximum.
- Time Complexity: O(n + m) where n is employees and m is departments
- Space Complexity: O(d) where d is the number of departments
185. Department Top Three Salaries
Description: Write a SQL query to find employees who are in the top three unique salaries in each department. The Employee table has columns id, name, salary, and departmentId. The Department table has columns id and name. Return department name, employee name, and salary. If there are fewer than three unique salaries, return all employees.
Java Solution:
// This is a SQL problem, not a Java problem
// SQL Solution using window function:
/*
SELECT Department, Employee, Salary
FROM (
SELECT d.name AS Department,
e.name AS Employee,
e.salary AS Salary,
DENSE_RANK() OVER (PARTITION BY e.departmentId
ORDER BY e.salary DESC) AS rnk
FROM Employee e
JOIN Department d ON e.departmentId = d.id
) AS ranked
WHERE rnk <= 3;
*/
// For demonstration, here's a Java implementation:
public List<TopThree> findTopThreeSalaries(
List<Employee> employees, List<Department> departments) {
Map<Integer, String> deptNames = new HashMap<>();
for (Department dept : departments) {
deptNames.put(dept.id, dept.name);
}
// Group employees by department
Map<Integer, List<Employee>> empByDept = new HashMap<>();
for (Employee emp : employees) {
empByDept.computeIfAbsent(emp.departmentId, k -> new ArrayList<>())
.add(emp);
}
List<TopThree> result = new ArrayList<>();
for (Map.Entry<Integer, List<Employee>> entry : empByDept.entrySet()) {
int deptId = entry.getKey();
List<Employee> deptEmps = entry.getValue();
// Get top 3 unique salaries
Set<Integer> uniqueSalaries = new TreeSet<>(Collections.reverseOrder());
for (Employee emp : deptEmps) {
uniqueSalaries.add(emp.salary);
}
Set<Integer> topThree = new HashSet<>();
int count = 0;
for (Integer salary : uniqueSalaries) {
if (count++ >= 3) break;
topThree.add(salary);
}
// Add employees with top 3 salaries
for (Employee emp : deptEmps) {
if (topThree.contains(emp.salary)) {
result.add(new TopThree(
deptNames.get(deptId), emp.name, emp.salary));
}
}
}
return result;
}
Explanation: The SQL solution uses DENSE_RANK() to assign ranks within each department and filters for top 3 ranks. In Java, we group employees by department, find the top 3 unique salaries per department using a sorted set, then include all employees with those salaries.
- Time Complexity: O(n log n) for sorting salaries per department
- Space Complexity: O(n) for grouping and storing results
186. Reverse Words in a String II
Description:
Given a character array s, reverse the order of the words. A word is defined as a sequence of non-space characters. The words in s will be separated by a single space. Your code must solve the problem in-place with O(1) extra space. This is the follow-up to problem 151 with stricter space requirements.
Java Solution:
public void reverseWords(char[] s) {
// Reverse the entire array
reverse(s, 0, s.length - 1);
// Reverse each word back to correct order
int start = 0;
for (int i = 0; i <= s.length; i++) {
if (i == s.length || s[i] == ' ') {
reverse(s, start, i - 1);
start = i + 1;
}
}
}
private void reverse(char[] s, int left, int right) {
while (left < right) {
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
Explanation: We use a two-step reversal approach. First, reverse the entire character array. This puts words in reverse order but each word is also reversed. Second, reverse each individual word to restore correct letter order. This achieves the desired result in-place with O(1) extra space.
- Time Complexity: O(n) where n is the length of the array
- Space Complexity: O(1) in-place reversal
187. Repeated DNA Sequences
Description:
The DNA sequence is composed of nucleotides: ‘A’, ‘C’, ‘G’, and ‘T’. When studying DNA, it’s useful to identify repeated sequences. Given a string s that represents a DNA sequence, return all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule. You may return the answer in any order.
Java Solution:
public List<String> findRepeatedDnaSequences(String s) {
if (s.length() < 10) return new ArrayList<>();
Set<String> seen = new HashSet<>();
Set<String> repeated = new HashSet<>();
for (int i = 0; i <= s.length() - 10; i++) {
String sequence = s.substring(i, i + 10);
if (seen.contains(sequence)) {
repeated.add(sequence);
} else {
seen.add(sequence);
}
}
return new ArrayList<>(repeated);
}
Explanation: We use a sliding window of size 10 to extract all possible 10-letter sequences. We maintain two sets: one to track sequences we’ve seen, and another to track sequences that appear more than once. When we encounter a sequence already in ‘seen’, we add it to ‘repeated’. Using sets ensures we don’t return duplicates.
- Time Complexity: O(n) where n is the length of the string
- Space Complexity: O(n) for storing sequences in sets
188. Best Time to Buy and Sell Stock IV
Description:
You are given an integer array prices where prices[i] is the price of a given stock on the ith day, and an integer k. Find the maximum profit you can achieve. You may complete at most k transactions. Note: You may not engage in multiple transactions simultaneously (you must sell before you buy again).
Java Solution:
public int maxProfit(int k, int[] prices) {
if (prices.length == 0 || k == 0) return 0;
// If k >= n/2, we can do unlimited transactions
if (k >= prices.length / 2) {
int profit = 0;
for (int i = 1; i < prices.length; i++) {
profit += Math.max(0, prices[i] - prices[i - 1]);
}
return profit;
}
// DP approach: dp[i][j] = max profit with at most i transactions by day j
int[][] dp = new int[k + 1][prices.length];
for (int i = 1; i <= k; i++) {
int maxDiff = -prices[0];
for (int j = 1; j < prices.length; j++) {
dp[i][j] = Math.max(dp[i][j - 1], prices[j] + maxDiff);
maxDiff = Math.max(maxDiff, dp[i - 1][j] - prices[j]);
}
}
return dp[k][prices.length - 1];
}
Explanation: This is a DP problem. When k is large (>= n/2), we can make unlimited transactions. Otherwise, we use dp[i][j] to represent max profit with at most i transactions by day j. For each transaction, we track the maximum difference (best buy price considering previous transactions) and update the maximum profit.
- Time Complexity: O(n × k) where n is the number of days
- Space Complexity: O(n × k) for the DP table
189. Rotate Array
Description:
Given an array, rotate the array to the right by k steps, where k is non-negative. For example, given [1,2,3,4,5,6,7] and k = 3, the result is [5,6,7,1,2,3,4]. Try to solve it in-place with O(1) extra space.
Java Solution:
public void rotate(int[] nums, int k) {
k = k % nums.length; // Handle k > length
if (k == 0) return;
// Reverse entire array
reverse(nums, 0, nums.length - 1);
// Reverse first k elements
reverse(nums, 0, k - 1);
// Reverse remaining elements
reverse(nums, k, nums.length - 1);
}
private void reverse(int[] nums, int left, int right) {
while (left < right) {
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
left++;
right--;
}
}
Explanation: We use the three-reversal trick. First, reverse the entire array. Then reverse the first k elements, and finally reverse the remaining elements. This achieves right rotation in-place with O(1) space. For example: [1,2,3,4,5,6,7] with k=3 becomes [7,6,5,4,3,2,1], then [5,6,7,4,3,2,1], then [5,6,7,1,2,3,4].
- Time Complexity: O(n) where n is the length of the array
- Space Complexity: O(1) in-place rotation
190. Reverse Bits
Description: Reverse bits of a given 32 bits unsigned integer. For example, the binary representation of 43261596 is 00000010100101000001111010011100, and reversing it gives 964176192 (00111001011110000010100101000000). Note that in some languages, such as Java, there is no unsigned integer type.
Java Solution:
public int reverseBits(int n) {
int result = 0;
for (int i = 0; i < 32; i++) {
// Shift result left to make room for next bit
result <<= 1;
// Add the least significant bit of n to result
result |= (n & 1);
// Shift n right to process next bit
n >>= 1;
}
return result;
}
Explanation: We process each of the 32 bits from right to left. For each bit, we shift the result left, extract the least significant bit of n using bitwise AND with 1, add it to result using OR, then shift n right. This effectively reverses the bit order. We must process all 32 bits to maintain the unsigned integer format.
- Time Complexity: O(1) fixed 32 iterations
- Space Complexity: O(1) constant space
191. Number of 1 Bits
Description: Write a function that takes an unsigned integer and returns the number of ‘1’ bits it has (also known as the Hamming weight). For example, the 32-bit integer 11 has binary representation 00000000000000000000000000001011, so the function should return 3.
Java Solution:
public int hammingWeight(int n) {
int count = 0;
while (n != 0) {
count++;
n = n & (n - 1); // Remove the rightmost 1 bit
}
return count;
}
// Alternative solution:
public int hammingWeightAlt(int n) {
int count = 0;
for (int i = 0; i < 32; i++) {
if ((n & 1) == 1) {
count++;
}
n >>>= 1; // Unsigned right shift
}
return count;
}
Explanation: We use Brian Kernighan’s algorithm: n & (n-1) removes the rightmost 1 bit. We repeat until n becomes 0, counting each iteration. This is more efficient than checking all 32 bits when there are few 1s. The alternative solution checks each bit using unsigned right shift and counts 1s.
- Time Complexity: O(k) where k is the number of 1 bits (best case O(1), worst case O(32))
- Space Complexity: O(1) constant space
192. Word Frequency
Description: Write a bash script to calculate the frequency of each word in a text file words.txt. For simplicity, you may assume that words.txt contains only lowercase characters and space characters, one word per line with no leading or trailing spaces. Output the words and their frequencies sorted by frequency in descending order.
Java Solution:
// This is a Bash/Shell scripting problem, not Java
// Bash Solution:
/*
cat words.txt | tr -s ' ' '\n' | sort | uniq -c | sort -rn | awk '{print $2, $1}'
*/
// Explanation of bash commands:
// tr -s ' ' '\n' - translate spaces to newlines (one word per line)
// sort - sort words alphabetically
// uniq -c - count unique occurrences
// sort -rn - sort numerically in reverse order
// awk '{print $2, $1}' - swap columns to show word first, then count
// For demonstration, here's a Java implementation:
import java.util.*;
import java.util.stream.*;
public List<WordFrequency> calculateFrequency(List<String> words) {
Map<String, Long> frequency = words.stream()
.collect(Collectors.groupingBy(
word -> word,
Collectors.counting()
));
return frequency.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.map(e -> new WordFrequency(e.getKey(), e.getValue()))
.collect(Collectors.toList());
}
Explanation: This is primarily a shell scripting problem. The bash solution uses Unix text processing tools to split, sort, count, and order words. In Java, we use streams to group words, count occurrences, and sort by frequency.
- Time Complexity: O(n log n) for sorting
- Space Complexity: O(n) for storing word frequencies
193. Valid Phone Numbers
Description: Given a text file file.txt that contains a list of phone numbers (one per line), write a one-liner bash script to print all valid phone numbers. You may assume that a valid phone number must appear in one of two formats: (xxx) xxx-xxxx or xxx-xxx-xxxx, where x denotes a digit.
Java Solution:
// This is a Bash/Shell scripting problem, not Java
// Bash Solution:
/*
grep -E '^(\([0-9]{3}\) |[0-9]{3}-)[0-9]{3}-[0-9]{4}$' file.txt
*/
// Alternative using awk:
/*
awk '/^(\([0-9]{3}\) |[0-9]{3}-)[0-9]{3}-[0-9]{4}$/' file.txt
*/
// For demonstration, here's a Java implementation:
import java.util.regex.*;
public List<String> validatePhoneNumbers(List<String> lines) {
String pattern = "^(\\([0-9]{3}\\) |[0-9]{3}-)[0-9]{3}-[0-9]{4}$";
Pattern p = Pattern.compile(pattern);
List<String> validNumbers = new ArrayList<>();
for (String line : lines) {
if (p.matcher(line).matches()) {
validNumbers.add(line);
}
}
return validNumbers;
}
Explanation: This is a shell scripting problem testing regex knowledge. The regex pattern matches either (xxx) xxx-xxxx or xxx-xxx-xxxx format. In Java, we compile the pattern and test each line. The key is understanding the two valid formats and using alternation in the regex.
- Time Complexity: O(n × m) where n is lines and m is average line length
- Space Complexity: O(k) where k is the number of valid phone numbers
194. Transpose File
Description: Given a text file file.txt, transpose its content. You may assume that each row has the same number of columns and each field is separated by a space character. Write a bash script to transpose the file.
Java Solution:
// This is a Bash/Shell scripting problem, not Java
// Bash Solution:
/*
awk '
{
for (i = 1; i <= NF; i++) {
if (NR == 1) {
s[i] = $i;
} else {
s[i] = s[i] " " $i;
}
}
}
END {
for (i = 1; s[i] != ""; i++) {
print s[i];
}
}' file.txt
*/
// For demonstration, here's a Java implementation:
public List<String> transposeFile(List<String> lines) {
if (lines.isEmpty()) return new ArrayList<>();
List<List<String>> matrix = new ArrayList<>();
for (String line : lines) {
matrix.add(Arrays.asList(line.split(" ")));
}
int rows = matrix.size();
int cols = matrix.get(0).size();
List<String> result = new ArrayList<>();
for (int j = 0; j < cols; j++) {
StringBuilder row = new StringBuilder();
for (int i = 0; i < rows; i++) {
if (i > 0) row.append(" ");
row.append(matrix.get(i).get(j));
}
result.add(row.toString());
}
return result;
}
Explanation: The bash solution uses awk to read the file, store each column in an array, and then print the transposed result. In Java, we parse the file into a 2D matrix, then iterate through columns (now rows) to build the transposed output.
- Time Complexity: O(rows × cols) for processing all elements
- Space Complexity: O(rows × cols) for storing the matrix
195. Tenth Line
Description: Given a text file file.txt, print just the 10th line of the file. If the file contains less than 10 lines, output nothing. This tests your understanding of basic bash text processing commands.
Java Solution:
// This is a Bash/Shell scripting problem, not Java
// Bash Solutions:
// Solution 1: Using sed
/*
sed -n '10p' file.txt
*/
// Solution 2: Using awk
/*
awk 'NR == 10' file.txt
*/
// Solution 3: Using head and tail
/*
head -n 10 file.txt | tail -n 1
*/
// For demonstration, here's a Java implementation:
import java.io.*;
import java.nio.file.*;
public String getTenthLine(String filename) throws IOException {
List<String> lines = Files.readAllLines(Paths.get(filename));
if (lines.size() < 10) {
return "";
}
return lines.get(9); // 0-indexed, so 9 is the 10th line
}
Explanation: This is a simple shell scripting problem. The sed solution uses -n to suppress output and ‘10p’ to print only line 10. The awk solution checks if the line number equals 10. The head/tail solution gets the first 10 lines and then the last of those. In Java, we read all lines and return the 10th if it exists.
- Time Complexity: O(n) to read n lines from the file
- Space Complexity: O(n) for storing all lines in Java (bash uses O(1))
196. Delete Duplicate Emails
Description: Write a SQL query to delete all duplicate email entries in a Person table, keeping only one unique email with the smallest id. The Person table has columns id (primary key) and email. After deletion, all emails should be unique.
Java Solution:
// This is a SQL problem, not a Java problem
// SQL Solution (MySQL):
/*
DELETE p1
FROM Person p1
JOIN Person p2
ON p1.email = p2.email
WHERE p1.id > p2.id;
*/
// Alternative using subquery (more portable):
/*
DELETE FROM Person
WHERE id NOT IN (
SELECT * FROM (
SELECT MIN(id)
FROM Person
GROUP BY email
) AS temp
);
*/
// For demonstration, here's a Java implementation:
public void deleteDuplicateEmails(List<Person> persons) {
Map<String, Person> uniqueEmails = new HashMap<>();
// Keep person with smallest id for each email
for (Person person : persons) {
if (!uniqueEmails.containsKey(person.email) ||
person.id < uniqueEmails.get(person.email).id) {
uniqueEmails.put(person.email, person);
}
}
// Remove persons not in uniqueEmails with smallest id
persons.removeIf(p ->
uniqueEmails.get(p.email).id != p.id
);
}
Explanation: The SQL solution performs a self-join to find duplicates and deletes entries with larger ids. The alternative uses a subquery to find minimum id per email. In Java, we use a map to track the person with smallest id for each email, then remove all others.
- Time Complexity: O(n) where n is the number of persons
- Space Complexity: O(k) where k is the number of unique emails
197. Rising Temperature
Description: Write a SQL query to find all dates’ id with higher temperatures compared to its previous dates (yesterday). The Weather table has columns id, recordDate, and temperature. Return the id of all dates with temperature higher than the previous day.
Java Solution:
// This is a SQL problem, not a Java problem
// SQL Solution:
/*
SELECT w1.id
FROM Weather w1
JOIN Weather w2
ON DATEDIFF(w1.recordDate, w2.recordDate) = 1
WHERE w1.temperature > w2.temperature;
*/
// Alternative using window functions:
/*
SELECT id
FROM (
SELECT id,
temperature,
LAG(temperature) OVER (ORDER BY recordDate) AS prev_temp,
LAG(recordDate) OVER (ORDER BY recordDate) AS prev_date,
recordDate
FROM Weather
) AS temp
WHERE temperature > prev_temp
AND DATEDIFF(recordDate, prev_date) = 1;
*/
// For demonstration, here's a Java implementation:
public List<Integer> findRisingTemperature(List<Weather> records) {
// Sort by date
records.sort(Comparator.comparing(w -> w.recordDate));
List<Integer> result = new ArrayList<>();
for (int i = 1; i < records.size(); i++) {
Weather curr = records.get(i);
Weather prev = records.get(i - 1);
// Check if consecutive days and temperature rose
if (curr.recordDate.equals(prev.recordDate.plusDays(1)) &&
curr.temperature > prev.temperature) {
result.add(curr.id);
}
}
return result;
}
Explanation: The SQL solution uses a self-join with DATEDIFF to find consecutive days where temperature increased. In Java, we sort by date, then iterate through consecutive records checking if they’re one day apart and temperature increased.
- Time Complexity: O(n log n) for sorting the records
- Space Complexity: O(k) where k is the number of rising temperature days
198. House Robber
Description:
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money. Adjacent houses have security systems connected, so you cannot rob two adjacent houses on the same night. Given an integer array nums representing the amount of money in each house, return the maximum amount of money you can rob without alerting the police.
Java Solution:
public int rob(int[] nums) {
if (nums.length == 0) return 0;
if (nums.length == 1) return nums[0];
int prev2 = 0;
int prev1 = 0;
for (int num : nums) {
int current = Math.max(prev1, prev2 + num);
prev2 = prev1;
prev1 = current;
}
return prev1;
}
Explanation: This is a dynamic programming problem. At each house, we have two choices: rob it (take current money + money from two houses back) or skip it (keep money from previous house). We maintain two variables: prev1 (max money up to previous house) and prev2 (max money up to two houses back). The recurrence is: current = max(prev1, prev2 + current_house). We optimize space by using variables instead of an array.
- Time Complexity: O(n) where n is the number of houses
- Space Complexity: O(1) constant space using variables
199. Binary Tree Right Side View
Description: Given the root of a binary tree, imagine yourself standing on the right side of it. Return the values of the nodes you can see ordered from top to bottom. Essentially, you need to find the rightmost node at each level of the tree.
Java Solution:
public List<Integer> rightSideView(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null) return result;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int levelSize = queue.size();
for (int i = 0; i < levelSize; i++) {
TreeNode node = queue.poll();
// Add the rightmost node of this level
if (i == levelSize - 1) {
result.add(node.val);
}
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
}
return result;
}
Explanation: We use level-order traversal (BFS) with a queue. At each level, we process all nodes and add only the rightmost node’s value to the result. We track level size to know when we’re at the last node of each level. This ensures we capture the right side view from top to bottom.
- Time Complexity: O(n) where n is the number of nodes
- Space Complexity: O(w) where w is the maximum width of the tree
200. Number of Islands
Description:
Given an m x n 2D binary grid grid which represents a map of ‘1’s (land) and ‘0’s (water), return the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are surrounded by water.
Java Solution:
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0) return 0;
int count = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == '1') {
count++;
dfs(grid, i, j);
}
}
}
return count;
}
private void dfs(char[][] grid, int i, int j) {
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length ||
grid[i][j] == '0') {
return;
}
grid[i][j] = '0'; // Mark as visited
// Explore all 4 directions
dfs(grid, i + 1, j);
dfs(grid, i - 1, j);
dfs(grid, i, j + 1);
dfs(grid, i, j - 1);
}
Explanation: We iterate through the grid. When we find a ‘1’ (unvisited land), we increment the island count and perform DFS to mark all connected land cells as visited by changing them to ‘0’. This prevents counting the same island multiple times. Each DFS call explores all 4 directions recursively.
- Time Complexity: O(m × n) where m and n are the grid dimensions
- Space Complexity: O(m × n) in worst case for recursion stack (all land)
201. Bitwise AND of Numbers Range
Description:
Given two integers left and right that represent the range [left, right], return the bitwise AND of all numbers in this range, inclusive. For example, given left = 5 (0101) and right = 7 (0111), the result is 4 (0100).
Java Solution:
public int rangeBitwiseAnd(int left, int right) {
int shift = 0;
// Find the common prefix
while (left != right) {
left >>= 1;
right >>= 1;
shift++;
}
return left << shift;
}
Explanation: The key insight is that the bitwise AND of a range will have 1s only in positions where all numbers share the same bit. We find the common left prefix by right-shifting both numbers until they’re equal. Then we left-shift back to get the result. All bits that differ in the range will become 0 in the final AND result.
- Time Complexity: O(log n) where n is the larger of left and right
- Space Complexity: O(1) constant space
202. Happy Number
Description:
A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits. Repeat the process until the number equals 1 (happy), or it loops endlessly in a cycle (not happy). Return true if n is a happy number, and false if not.
Java Solution:
public boolean isHappy(int n) {
Set<Integer> seen = new HashSet<>();
while (n != 1 && !seen.contains(n)) {
seen.add(n);
n = getSumOfSquares(n);
}
return n == 1;
}
private int getSumOfSquares(int n) {
int sum = 0;
while (n > 0) {
int digit = n % 10;
sum += digit * digit;
n /= 10;
}
return sum;
}
Explanation: We repeatedly calculate the sum of squares of digits. If we reach 1, it’s happy. If we see a number we’ve seen before, we’re in a cycle and it’s not happy. We use a HashSet to detect cycles. Alternative solution uses Floyd’s cycle detection (slow/fast pointers) for O(1) space.
- Time Complexity: O(log n) for the number of digits processed
- Space Complexity: O(log n) for the set storing seen numbers
203. Remove Linked List Elements
Description:
Given the head of a linked list and an integer val, remove all the nodes of the linked list that has Node.val == val, and return the new head. This tests your understanding of linked list manipulation and handling edge cases.
Java Solution:
public ListNode removeElements(ListNode head, int val) {
// Create a dummy node to handle edge cases
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode current = dummy;
while (current.next != null) {
if (current.next.val == val) {
current.next = current.next.next;
} else {
current = current.next;
}
}
return dummy.next;
}
Explanation: We use a dummy node to simplify handling the case where head needs to be removed. We iterate through the list, and when we find a node with the target value, we skip it by adjusting pointers. The dummy node ensures we always have a previous node to work with, avoiding special cases for the head.
- Time Complexity: O(n) where n is the number of nodes
- Space Complexity: O(1) constant space
204. Count Primes
Description:
Given an integer n, return the number of prime numbers that are strictly less than n. For example, if n = 10, there are 4 prime numbers less than 10: 2, 3, 5, 7.
Java Solution:
public int countPrimes(int n) {
if (n <= 2) return 0;
boolean[] isPrime = new boolean[n];
Arrays.fill(isPrime, true);
isPrime[0] = isPrime[1] = false;
// Sieve of Eratosthenes
for (int i = 2; i * i < n; i++) {
if (isPrime[i]) {
for (int j = i * i; j < n; j += i) {
isPrime[j] = false;
}
}
}
int count = 0;
for (boolean prime : isPrime) {
if (prime) count++;
}
return count;
}
Explanation: We use the Sieve of Eratosthenes algorithm. Start with all numbers marked as prime. For each prime number i, mark all its multiples (starting from i²) as non-prime. We only need to check up to √n because any composite number less than n must have a factor ≤ √n. Finally, count the remaining primes.
- Time Complexity: O(n log log n) using Sieve of Eratosthenes
- Space Complexity: O(n) for the boolean array
205. Isomorphic Strings
Description:
Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the characters in s can be replaced to get t. All occurrences of a character must be replaced with another character while preserving the order. No two characters may map to the same character, but a character may map to itself.
Java Solution:
public boolean isIsomorphic(String s, String t) {
if (s.length() != t.length()) return false;
Map<Character, Character> mapST = new HashMap<>();
Map<Character, Character> mapTS = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
char c1 = s.charAt(i);
char c2 = t.charAt(i);
if (mapST.containsKey(c1)) {
if (mapST.get(c1) != c2) return false;
} else {
mapST.put(c1, c2);
}
if (mapTS.containsKey(c2)) {
if (mapTS.get(c2) != c1) return false;
} else {
mapTS.put(c2, c1);
}
}
return true;
}
Explanation: We need bidirectional mapping to ensure one-to-one correspondence. We use two maps: one from s to t and one from t to s. For each character pair, we check if they’re already mapped. If yes, verify the mapping is consistent. If no, create the mapping. This ensures no two characters map to the same character in either direction.
- Time Complexity: O(n) where n is the length of the strings
- Space Complexity: O(1) since we have at most 256 ASCII characters
206. Reverse Linked List
Description: Given the head of a singly linked list, reverse the list, and return the reversed list. This is a fundamental linked list problem that tests your understanding of pointer manipulation.
Java Solution:
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode current = head;
while (current != null) {
ListNode next = current.next;
current.next = prev;
prev = current;
current = next;
}
return prev;
}
// Recursive solution:
public ListNode reverseListRecursive(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode newHead = reverseListRecursive(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
Explanation: Iterative approach: We maintain three pointers (prev, current, next). For each node, we save the next node, reverse the current node’s pointer to prev, then advance all pointers. Recursive approach: Recursively reverse the rest of the list, then make the next node point back to current and break the forward link.
- Time Complexity: O(n) where n is the number of nodes
- Space Complexity: O(1) iterative, O(n) recursive due to call stack
207. Course Schedule
Description:
There are a total of numCourses courses labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai. Return true if you can finish all courses, otherwise return false. This is essentially cycle detection in a directed graph.
Java Solution:
public boolean canFinish(int numCourses, int[][] prerequisites) {
List<List<Integer>> graph = new ArrayList<>();
for (int i = 0; i < numCourses; i++) {
graph.add(new ArrayList<>());
}
for (int[] pre : prerequisites) {
graph.get(pre[1]).add(pre[0]);
}
int[] visited = new int[numCourses]; // 0: unvisited, 1: visiting, 2: visited
for (int i = 0; i < numCourses; i++) {
if (hasCycle(graph, visited, i)) {
return false;
}
}
return true;
}
private boolean hasCycle(List<List<Integer>> graph, int[] visited, int course) {
if (visited[course] == 1) return true; // Cycle detected
if (visited[course] == 2) return false; // Already processed
visited[course] = 1; // Mark as visiting
for (int next : graph.get(course)) {
if (hasCycle(graph, visited, next)) {
return true;
}
}
visited[course] = 2; // Mark as visited
return false;
}
Explanation: We model this as a directed graph where an edge from A to B means A must be taken before B. The solution uses DFS to detect cycles. If there’s a cycle, it’s impossible to finish all courses. We use three states: unvisited, visiting (in current DFS path), and visited (fully processed).
- Time Complexity: O(V + E) where V is courses and E is prerequisites
- Space Complexity: O(V + E) for the graph and recursion stack
208. Implement Trie (Prefix Tree)
Description:
A trie (prefix tree) is a tree data structure used to efficiently store and retrieve keys in a dataset of strings. Implement the Trie class with insert(word), search(word), and startsWith(prefix) methods.
Java Solution:
class Trie {
private class TrieNode {
TrieNode[] children = new TrieNode[26];
boolean isEnd = false;
}
private TrieNode root;
public Trie() {
root = new TrieNode();
}
public void insert(String word) {
TrieNode node = root;
for (char c : word.toCharArray()) {
int index = c - 'a';
if (node.children[index] == null) {
node.children[index] = new TrieNode();
}
node = node.children[index];
}
node.isEnd = true;
}
public boolean search(String word) {
TrieNode node = searchPrefix(word);
return node != null && node.isEnd;
}
public boolean startsWith(String prefix) {
return searchPrefix(prefix) != null;
}
private TrieNode searchPrefix(String prefix) {
TrieNode node = root;
for (char c : prefix.toCharArray()) {
int index = c - 'a';
if (node.children[index] == null) {
return null;
}
node = node.children[index];
}
return node;
}
}
Explanation: A Trie uses nodes with 26 children (for each letter). Each node has a boolean flag indicating if it’s the end of a word. Insert creates nodes as needed. Search checks if a path exists and ends at a word. StartsWith only checks if the path exists.
- Time Complexity: O(m) for all operations where m is the key length
- Space Complexity: O(n × m) worst case for n words of length m
209. Minimum Size Subarray Sum
Description: Find minimum length subarray with sum >= target.
Java Solution:
public int minSubArrayLen(int target, int[] nums) {
int left = 0, sum = 0, minLen = Integer.MAX_VALUE;
for (int right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum >= target) {
minLen = Math.min(minLen, right - left + 1);
sum -= nums[left++];
}
}
return minLen == Integer.MAX_VALUE ? 0 : minLen;
}
Explanation: Sliding window: expand right to increase sum, shrink left while sum >= target. Track minimum window size.
- Time Complexity: O(n)
- Space Complexity: O(1)
210. Course Schedule II
Description: Return order to finish all courses (topological sort).
Java Solution:
public int[] findOrder(int numCourses, int[][] prerequisites) {
List<List<Integer>> graph = new ArrayList<>();
int[] indegree = new int[numCourses];
for (int i = 0; i < numCourses; i++) graph.add(new ArrayList<>());
for (int[] pre : prerequisites) {
graph.get(pre[1]).add(pre[0]);
indegree[pre[0]]++;
}
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < numCourses; i++) {
if (indegree[i] == 0) queue.offer(i);
}
int[] result = new int[numCourses];
int idx = 0;
while (!queue.isEmpty()) {
int course = queue.poll();
result[idx++] = course;
for (int next : graph.get(course)) {
if (--indegree[next] == 0) queue.offer(next);
}
}
return idx == numCourses ? result : new int[0];
}
Explanation: Kahn’s algorithm: start with courses having no prerequisites, process them, reduce indegrees, add newly available courses.
- Time Complexity: O(V + E)
- Space Complexity: O(V + E)
211. Design Add and Search Words Data Structure
Description: Design data structure supporting add and search with ’.’ wildcard.
Java Solution:
class WordDictionary {
private TrieNode root;
class TrieNode {
TrieNode[] children = new TrieNode[26];
boolean isWord;
}
public WordDictionary() { root = new TrieNode(); }
public void addWord(String word) {
TrieNode node = root;
for (char c : word.toCharArray()) {
if (node.children[c - 'a'] == null) node.children[c - 'a'] = new TrieNode();
node = node.children[c - 'a'];
}
node.isWord = true;
}
public boolean search(String word) { return searchHelper(word, 0, root); }
private boolean searchHelper(String word, int idx, TrieNode node) {
if (idx == word.length()) return node.isWord;
char c = word.charAt(idx);
if (c == '.') {
for (TrieNode child : node.children) {
if (child != null && searchHelper(word, idx + 1, child)) return true;
}
return false;
}
return node.children[c - 'a'] != null && searchHelper(word, idx + 1, node.children[c - 'a']);
}
}
Explanation: Trie with DFS search. For ’.’, try all children recursively. For letters, follow the specific path.
- Time Complexity: O(m) add, O(26^m) worst search
- Space Complexity: O(n × m)
212. Word Search II
Description: Find all words from dictionary that exist in board.
Java Solution:
public List<String> findWords(char[][] board, String[] words) {
List<String> result = new ArrayList<>();
TrieNode root = buildTrie(words);
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
dfs(board, i, j, root, result);
}
}
return result;
}
private void dfs(char[][] board, int i, int j, TrieNode node, List<String> result) {
char c = board[i][j];
if (c == '#' || node.children[c - 'a'] == null) return;
node = node.children[c - 'a'];
if (node.word != null) {
result.add(node.word);
node.word = null;
}
board[i][j] = '#';
if (i > 0) dfs(board, i - 1, j, node, result);
if (j > 0) dfs(board, i, j - 1, node, result);
if (i < board.length - 1) dfs(board, i + 1, j, node, result);
if (j < board[0].length - 1) dfs(board, i, j + 1, node, result);
board[i][j] = c;
}
class TrieNode {
TrieNode[] children = new TrieNode[26];
String word;
}
private TrieNode buildTrie(String[] words) {
TrieNode root = new TrieNode();
for (String w : words) {
TrieNode node = root;
for (char c : w.toCharArray()) {
if (node.children[c - 'a'] == null) node.children[c - 'a'] = new TrieNode();
node = node.children[c - 'a'];
}
node.word = w;
}
return root;
}
Explanation: Build trie from words, DFS from each cell following trie paths. Prune paths not in trie for efficiency.
- Time Complexity: O(m × n × 4^L)
- Space Complexity: O(sum of word lengths)
213. House Robber II
Description: Rob houses in circle (first and last are adjacent).
Java Solution:
public int rob(int[] nums) {
if (nums.length == 1) return nums[0];
return Math.max(robRange(nums, 0, nums.length - 2), robRange(nums, 1, nums.length - 1));
}
private int robRange(int[] nums, int start, int end) {
int prev2 = 0, prev1 = 0;
for (int i = start; i <= end; i++) {
int curr = Math.max(prev1, prev2 + nums[i]);
prev2 = prev1;
prev1 = curr;
}
return prev1;
}
Explanation: Since first and last are adjacent, we can’t rob both. Solve twice: excluding last, excluding first. Take maximum.
- Time Complexity: O(n)
- Space Complexity: O(1)
214. Shortest Palindrome
Description: Find shortest palindrome by adding characters to front.
Java Solution:
public String shortestPalindrome(String s) {
String rev = new StringBuilder(s).reverse().toString();
String combined = s + "#" + rev;
int[] lps = computeLPS(combined);
int addLen = s.length() - lps[combined.length() - 1];
return rev.substring(0, addLen) + s;
}
private int[] computeLPS(String s) {
int[] lps = new int[s.length()];
int len = 0, i = 1;
while (i < s.length()) {
if (s.charAt(i) == s.charAt(len)) {
lps[i++] = ++len;
} else if (len > 0) {
len = lps[len - 1];
} else {
i++;
}
}
return lps;
}
Explanation: Use KMP failure function on s + ”#” + reverse(s). LPS value at end gives longest palindrome prefix. Add remaining reverse prefix.
- Time Complexity: O(n)
- Space Complexity: O(n)
215. Kth Largest Element in an Array
Description: Find kth largest element.
Java Solution:
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
for (int num : nums) {
minHeap.offer(num);
if (minHeap.size() > k) minHeap.poll();
}
return minHeap.peek();
}
Explanation: Maintain min-heap of size k. After processing all elements, heap top is kth largest.
- Time Complexity: O(n log k)
- Space Complexity: O(k)
216. Combination Sum III
Description: Find k numbers summing to n using 1-9.
Java Solution:
public List<List<Integer>> combinationSum3(int k, int n) {
List<List<Integer>> result = new ArrayList<>();
backtrack(result, new ArrayList<>(), k, n, 1);
return result;
}
private void backtrack(List<List<Integer>> result, List<Integer> curr, int k, int n, int start) {
if (curr.size() == k && n == 0) {
result.add(new ArrayList<>(curr));
return;
}
if (curr.size() >= k || n < 0) return;
for (int i = start; i <= 9; i++) {
curr.add(i);
backtrack(result, curr, k, n - i, i + 1);
curr.remove(curr.size() - 1);
}
}
Explanation: Backtracking with constraints: exactly k numbers, sum equals n, use each digit at most once.
- Time Complexity: O(C(9,k))
- Space Complexity: O(k)
217. Contains Duplicate
Description: Check if array contains any duplicate.
Java Solution:
public boolean containsDuplicate(int[] nums) {
Set<Integer> seen = new HashSet<>();
for (int num : nums) {
if (!seen.add(num)) return true;
}
return false;
}
Explanation: HashSet.add() returns false if element exists. Return true on first duplicate found.
- Time Complexity: O(n)
- Space Complexity: O(n)
218. The Skyline Problem
Description: Return skyline formed by buildings.
Java Solution:
public List<List<Integer>> getSkyline(int[][] buildings) {
List<int[]> events = new ArrayList<>();
for (int[] b : buildings) {
events.add(new int[]{b[0], -b[2]});
events.add(new int[]{b[1], b[2]});
}
Collections.sort(events, (a, b) -> a[0] != b[0] ? a[0] - b[0] : a[1] - b[1]);
List<List<Integer>> result = new ArrayList<>();
TreeMap<Integer, Integer> heights = new TreeMap<>(Collections.reverseOrder());
heights.put(0, 1);
int prevMax = 0;
for (int[] e : events) {
if (e[1] < 0) {
heights.merge(-e[1], 1, Integer::sum);
} else {
heights.merge(e[1], -1, Integer::sum);
if (heights.get(e[1]) == 0) heights.remove(e[1]);
}
int currMax = heights.firstKey();
if (currMax != prevMax) {
result.add(Arrays.asList(e[0], currMax));
prevMax = currMax;
}
}
return result;
}
Explanation: Events at building starts (negative height) and ends. Use TreeMap to track active heights. Add to result when max height changes.
- Time Complexity: O(n log n)
- Space Complexity: O(n)
219. Contains Duplicate II
Description: Check if duplicate exists within k distance.
Java Solution:
public boolean containsNearbyDuplicate(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if (map.containsKey(nums[i]) && i - map.get(nums[i]) <= k) {
return true;
}
map.put(nums[i], i);
}
return false;
}
Explanation: Track last seen index of each number. Check if current index minus last index is within k.
- Time Complexity: O(n)
- Space Complexity: O(n)
220. Contains Duplicate III
Description: Check if elements within k distance have difference <= t.
Java Solution:
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
TreeSet<Long> set = new TreeSet<>();
for (int i = 0; i < nums.length; i++) {
Long ceiling = set.ceiling((long)nums[i] - t);
if (ceiling != null && ceiling <= (long)nums[i] + t) return true;
set.add((long)nums[i]);
if (i >= k) set.remove((long)nums[i - k]);
}
return false;
}
Explanation: Maintain sorted set of last k elements. For each number, check if any value in [num-t, num+t] exists.
- Time Complexity: O(n log k)
- Space Complexity: O(k)
221. Maximal Square
Description: Find largest square of 1s in binary matrix.
Java Solution:
public int maximalSquare(char[][] matrix) {
int m = matrix.length, n = matrix[0].length;
int[][] dp = new int[m + 1][n + 1];
int maxSide = 0;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (matrix[i - 1][j - 1] == '1') {
dp[i][j] = 1 + Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1]));
maxSide = Math.max(maxSide, dp[i][j]);
}
}
}
return maxSide * maxSide;
}
Explanation: DP where dp[i][j] = side of largest square ending at (i,j). It’s 1 + min of three neighbors if current cell is ‘1’.
- Time Complexity: O(m×n)
- Space Complexity: O(m×n)
222. Count Complete Tree Nodes
Description: Count nodes in complete binary tree.
Java Solution:
public int countNodes(TreeNode root) {
if (root == null) return 0;
int leftHeight = getHeight(root.left);
int rightHeight = getHeight(root.right);
if (leftHeight == rightHeight) {
return (1 << leftHeight) + countNodes(root.right);
} else {
return (1 << rightHeight) + countNodes(root.left);
}
}
private int getHeight(TreeNode node) {
int h = 0;
while (node != null) {
h++;
node = node.left;
}
return h;
}
Explanation: If left height equals right height, left subtree is perfect (2^h - 1 nodes), recurse on right. Otherwise, right subtree is perfect, recurse on left.
- Time Complexity: O(log²n)
- Space Complexity: O(log n)
223. Rectangle Area
Description: Find total area covered by two rectangles.
Java Solution:
public int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
int area1 = (ax2 - ax1) * (ay2 - ay1);
int area2 = (bx2 - bx1) * (by2 - by1);
int overlapWidth = Math.min(ax2, bx2) - Math.max(ax1, bx1);
int overlapHeight = Math.min(ay2, by2) - Math.max(ay1, by1);
int overlap = 0;
if (overlapWidth > 0 && overlapHeight > 0) {
overlap = overlapWidth * overlapHeight;
}
return area1 + area2 - overlap;
}
Explanation: Total = area1 + area2 - overlap. Overlap exists if rectangles intersect; calculate overlap dimensions.
- Time Complexity: O(1)
- Space Complexity: O(1)
224. Basic Calculator
Description: Implement basic calculator with +, -, and parentheses.
Java Solution:
public int calculate(String s) {
Deque<Integer> stack = new ArrayDeque<>();
int result = 0, num = 0, sign = 1;
for (char c : s.toCharArray()) {
if (Character.isDigit(c)) {
num = num * 10 + (c - '0');
} else if (c == '+') {
result += sign * num;
num = 0;
sign = 1;
} else if (c == '-') {
result += sign * num;
num = 0;
sign = -1;
} else if (c == '(') {
stack.push(result);
stack.push(sign);
result = 0;
sign = 1;
} else if (c == ')') {
result += sign * num;
num = 0;
result *= stack.pop();
result += stack.pop();
}
}
return result + sign * num;
}
Explanation: Track current result and sign. On ’(’, save state to stack. On ’)’, combine with saved state.
- Time Complexity: O(n)
- Space Complexity: O(n)
225. Implement Stack using Queues
Description: Implement stack using two queues.
Java Solution:
class MyStack {
private Queue<Integer> queue;
public MyStack() { queue = new LinkedList<>(); }
public void push(int x) {
queue.offer(x);
for (int i = 0; i < queue.size() - 1; i++) {
queue.offer(queue.poll());
}
}
public int pop() { return queue.poll(); }
public int top() { return queue.peek(); }
public boolean empty() { return queue.isEmpty(); }
}
Explanation: Single queue approach: on push, rotate all existing elements after new element so new element is at front.
- Time Complexity: O(n) push, O(1) others
- Space Complexity: O(n)
226. Invert Binary Tree
Description: Invert/mirror a binary tree.
Java Solution:
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
TreeNode temp = root.left;
root.left = invertTree(root.right);
root.right = invertTree(temp);
return root;
}
Explanation: Recursively swap left and right children for each node.
- Time Complexity: O(n)
- Space Complexity: O(h)
227. Basic Calculator II
Description: Implement calculator with +, -, *, /.
Java Solution:
public int calculate(String s) {
Deque<Integer> stack = new ArrayDeque<>();
int num = 0;
char op = '+';
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isDigit(c)) {
num = num * 10 + (c - '0');
}
if ((!Character.isDigit(c) && c != ' ') || i == s.length() - 1) {
if (op == '+') stack.push(num);
else if (op == '-') stack.push(-num);
else if (op == '*') stack.push(stack.pop() * num);
else if (op == '/') stack.push(stack.pop() / num);
op = c;
num = 0;
}
}
int result = 0;
while (!stack.isEmpty()) result += stack.pop();
return result;
}
Explanation: Process * and / immediately, defer + and - to stack. Sum stack at end.
- Time Complexity: O(n)
- Space Complexity: O(n)
228. Summary Ranges
Description: Return summary of consecutive ranges.
Java Solution:
public List<String> summaryRanges(int[] nums) {
List<String> result = new ArrayList<>();
int i = 0;
while (i < nums.length) {
int start = nums[i];
while (i + 1 < nums.length && nums[i + 1] == nums[i] + 1) {
i++;
}
if (start == nums[i]) {
result.add(String.valueOf(start));
} else {
result.add(start + "->" + nums[i]);
}
i++;
}
return result;
}
Explanation: Find consecutive sequences. Format as “a” or “a->b” based on range length.
- Time Complexity: O(n)
- Space Complexity: O(1)
229. Majority Element II
Description: Find elements appearing more than n/3 times.
Java Solution:
public List<Integer> majorityElement(int[] nums) {
int cand1 = 0, cand2 = 1, count1 = 0, count2 = 0;
for (int num : nums) {
if (num == cand1) count1++;
else if (num == cand2) count2++;
else if (count1 == 0) { cand1 = num; count1 = 1; }
else if (count2 == 0) { cand2 = num; count2 = 1; }
else { count1--; count2--; }
}
count1 = count2 = 0;
for (int num : nums) {
if (num == cand1) count1++;
else if (num == cand2) count2++;
}
List<Integer> result = new ArrayList<>();
if (count1 > nums.length / 3) result.add(cand1);
if (count2 > nums.length / 3) result.add(cand2);
return result;
}
Explanation: Boyer-Moore voting for two candidates. At most 2 elements can appear > n/3 times. Verify counts in second pass.
- Time Complexity: O(n)
- Space Complexity: O(1)
230. Kth Smallest Element in a BST
Description: Find kth smallest element in BST.
Java Solution:
public int kthSmallest(TreeNode root, int k) {
Deque<TreeNode> stack = new ArrayDeque<>();
TreeNode curr = root;
while (true) {
while (curr != null) {
stack.push(curr);
curr = curr.left;
}
curr = stack.pop();
if (--k == 0) return curr.val;
curr = curr.right;
}
}
Explanation: Inorder traversal gives sorted order. Count nodes during traversal and return when count reaches k.
- Time Complexity: O(H + k)
- Space Complexity: O(H)
231. Power of Two
Description: Check if n is a power of two.
Java Solution:
public boolean isPowerOfTwo(int n) {
return n > 0 && (n & (n - 1)) == 0;
}
Explanation: Power of 2 has single bit set. n & (n-1) clears lowest bit. If result is 0, only one bit was set.
- Time Complexity: O(1)
- Space Complexity: O(1)
232. Implement Queue using Stacks
Description: Implement queue using two stacks.
Java Solution:
class MyQueue {
private Stack<Integer> input = new Stack<>();
private Stack<Integer> output = new Stack<>();
public void push(int x) { input.push(x); }
public int pop() {
peek();
return output.pop();
}
public int peek() {
if (output.isEmpty()) {
while (!input.isEmpty()) {
output.push(input.pop());
}
}
return output.peek();
}
public boolean empty() { return input.isEmpty() && output.isEmpty(); }
}
Explanation: Lazy transfer: move from input to output only when output is empty. This reverses order, achieving FIFO.
- Time Complexity: O(1) amortized
- Space Complexity: O(n)
233. Number of Digit One
Description: Count total 1s appearing in all numbers from 1 to n.
Java Solution:
public int countDigitOne(int n) {
int count = 0;
for (long i = 1; i <= n; i *= 10) {
long divider = i * 10;
count += (n / divider) * i + Math.min(Math.max(n % divider - i + 1, 0), i);
}
return count;
}
Explanation: Count 1s at each digit position. For position i, count full cycles plus partial based on current digit value.
- Time Complexity: O(log n)
- Space Complexity: O(1)
234. Palindrome Linked List
Description: Check if linked list is palindrome.
Java Solution:
public boolean isPalindrome(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode prev = null;
while (slow != null) {
ListNode next = slow.next;
slow.next = prev;
prev = slow;
slow = next;
}
while (prev != null) {
if (head.val != prev.val) return false;
head = head.next;
prev = prev.next;
}
return true;
}
Explanation: Find middle, reverse second half, compare with first half. O(1) space by modifying list.
- Time Complexity: O(n)
- Space Complexity: O(1)
235. Lowest Common Ancestor of a Binary Search Tree
Description: Find LCA in BST.
Java Solution:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while (root != null) {
if (p.val < root.val && q.val < root.val) root = root.left;
else if (p.val > root.val && q.val > root.val) root = root.right;
else return root;
}
return null;
}
Explanation: Use BST property. If both nodes smaller, go left. Both larger, go right. Otherwise current node is LCA.
- Time Complexity: O(H)
- Space Complexity: O(1)
236. Lowest Common Ancestor of a Binary Tree
Description: Find LCA in general binary tree.
Java Solution:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left != null && right != null) return root;
return left != null ? left : right;
}
Explanation: Recursively search both subtrees. If p and q are in different subtrees, current node is LCA. Otherwise, return the non-null result.
- Time Complexity: O(n)
- Space Complexity: O(H)
237. Delete Node in a Linked List
Description: Delete node given only access to that node.
Java Solution:
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
Explanation: Copy next node’s value to current, then skip next node. Effectively deletes current node.
- Time Complexity: O(1)
- Space Complexity: O(1)
238. Product of Array Except Self
Description: Return array where each element is product of all others.
Java Solution:
public int[] productExceptSelf(int[] nums) {
int n = nums.length;
int[] result = new int[n];
result[0] = 1;
for (int i = 1; i < n; i++) {
result[i] = result[i - 1] * nums[i - 1];
}
int right = 1;
for (int i = n - 1; i >= 0; i--) {
result[i] *= right;
right *= nums[i];
}
return result;
}
Explanation: Two passes: first stores prefix products, second multiplies by suffix products. No division used.
- Time Complexity: O(n)
- Space Complexity: O(1) excluding output
239. Sliding Window Maximum
Description: Find maximum in each sliding window of size k.
Java Solution:
public int[] maxSlidingWindow(int[] nums, int k) {
Deque<Integer> deque = new ArrayDeque<>();
int[] result = new int[nums.length - k + 1];
for (int i = 0; i < nums.length; i++) {
while (!deque.isEmpty() && deque.peekFirst() < i - k + 1) {
deque.pollFirst();
}
while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
deque.pollLast();
}
deque.offerLast(i);
if (i >= k - 1) {
result[i - k + 1] = nums[deque.peekFirst()];
}
}
return result;
}
Explanation: Monotonic decreasing deque stores indices. Remove out-of-window elements from front, smaller elements from back.
- Time Complexity: O(n)
- Space Complexity: O(k)
240. Search a 2D Matrix II
Description: Search in row-sorted and column-sorted matrix.
Java Solution:
public boolean searchMatrix(int[][] matrix, int target) {
int row = 0, col = matrix[0].length - 1;
while (row < matrix.length && col >= 0) {
if (matrix[row][col] == target) return true;
if (matrix[row][col] > target) col--;
else row++;
}
return false;
}
Explanation: Start from top-right. If current > target, go left. If current < target, go down. Eliminates row or column each step.
- Time Complexity: O(m + n)
- Space Complexity: O(1)
241. Different Ways to Add Parentheses
Description: Return all results from different ways to group expression.
Java Solution:
public List<Integer> diffWaysToCompute(String expression) {
List<Integer> result = new ArrayList<>();
for (int i = 0; i < expression.length(); i++) {
char c = expression.charAt(i);
if (c == '+' || c == '-' || c == '*') {
List<Integer> left = diffWaysToCompute(expression.substring(0, i));
List<Integer> right = diffWaysToCompute(expression.substring(i + 1));
for (int l : left) {
for (int r : right) {
if (c == '+') result.add(l + r);
else if (c == '-') result.add(l - r);
else result.add(l * r);
}
}
}
}
if (result.isEmpty()) result.add(Integer.parseInt(expression));
return result;
}
Explanation: Divide and conquer: split at each operator, recursively compute left and right, combine all pairs.
- Time Complexity: O(4^n / n^(3/2)) - Catalan
- Space Complexity: O(4^n / n^(3/2))
242. Valid Anagram
Description: Check if t is anagram of s.
Java Solution:
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()) return false;
int[] count = new int[26];
for (int i = 0; i < s.length(); i++) {
count[s.charAt(i) - 'a']++;
count[t.charAt(i) - 'a']--;
}
for (int c : count) {
if (c != 0) return false;
}
return true;
}
Explanation: Count characters: increment for s, decrement for t. If all counts are 0, strings are anagrams.
- Time Complexity: O(n)
- Space Complexity: O(1)
243. Shortest Word Distance
Description: Find shortest distance between two words in array.
Java Solution:
public int shortestDistance(String[] words, String word1, String word2) {
int idx1 = -1, idx2 = -1, minDist = Integer.MAX_VALUE;
for (int i = 0; i < words.length; i++) {
if (words[i].equals(word1)) idx1 = i;
else if (words[i].equals(word2)) idx2 = i;
if (idx1 != -1 && idx2 != -1) {
minDist = Math.min(minDist, Math.abs(idx1 - idx2));
}
}
return minDist;
}
Explanation: Track most recent positions of both words. Update minimum distance when both have been seen.
- Time Complexity: O(n)
- Space Complexity: O(1)
244. Shortest Word Distance II
Description: Design class for multiple queries of shortest word distance.
Java Solution:
class WordDistance {
private Map<String, List<Integer>> locations;
public WordDistance(String[] words) {
locations = new HashMap<>();
for (int i = 0; i < words.length; i++) {
locations.computeIfAbsent(words[i], k -> new ArrayList<>()).add(i);
}
}
public int shortest(String word1, String word2) {
List<Integer> loc1 = locations.get(word1);
List<Integer> loc2 = locations.get(word2);
int i = 0, j = 0, minDist = Integer.MAX_VALUE;
while (i < loc1.size() && j < loc2.size()) {
minDist = Math.min(minDist, Math.abs(loc1.get(i) - loc2.get(j)));
if (loc1.get(i) < loc2.get(j)) i++;
else j++;
}
return minDist;
}
}
Explanation: Precompute word positions. Two-pointer merge on sorted position lists finds minimum distance.
- Time Complexity: O(n) init, O(m + k) query
- Space Complexity: O(n)
245. Shortest Word Distance III
Description: Find shortest distance even if words are the same.
Java Solution:
public int shortestWordDistance(String[] words, String word1, String word2) {
int idx1 = -1, idx2 = -1, minDist = Integer.MAX_VALUE;
boolean same = word1.equals(word2);
for (int i = 0; i < words.length; i++) {
if (words[i].equals(word1)) {
if (same) {
idx2 = idx1;
idx1 = i;
} else {
idx1 = i;
}
} else if (words[i].equals(word2)) {
idx2 = i;
}
if (idx1 != -1 && idx2 != -1) {
minDist = Math.min(minDist, Math.abs(idx1 - idx2));
}
}
return minDist;
}
Explanation: Similar to 243, but handle same-word case by shifting previous position.
- Time Complexity: O(n)
- Space Complexity: O(1)
246. Strobogrammatic Number
Description: Check if number looks same when rotated 180 degrees.
Java Solution:
public boolean isStrobogrammatic(String num) {
Map<Character, Character> map = Map.of('0', '0', '1', '1', '6', '9', '8', '8', '9', '6');
int left = 0, right = num.length() - 1;
while (left <= right) {
char l = num.charAt(left), r = num.charAt(right);
if (!map.containsKey(l) || map.get(l) != r) return false;
left++;
right--;
}
return true;
}
Explanation: Check if each pair (from outside in) maps correctly under 180° rotation. Valid pairs: 0-0, 1-1, 6-9, 8-8, 9-6.
- Time Complexity: O(n)
- Space Complexity: O(1)
247. Strobogrammatic Number II
Description: Find all strobogrammatic numbers of length n.
Java Solution:
public List<String> findStrobogrammatic(int n) {
return helper(n, n);
}
private List<String> helper(int n, int total) {
if (n == 0) return Arrays.asList("");
if (n == 1) return Arrays.asList("0", "1", "8");
List<String> middles = helper(n - 2, total);
List<String> result = new ArrayList<>();
for (String middle : middles) {
if (n != total) result.add("0" + middle + "0");
result.add("1" + middle + "1");
result.add("6" + middle + "9");
result.add("8" + middle + "8");
result.add("9" + middle + "6");
}
return result;
}
Explanation: Build recursively from center outward. Add valid pairs around middle. Skip leading zeros except for n=1.
- Time Complexity: O(5^(n/2))
- Space Complexity: O(5^(n/2))
248. Strobogrammatic Number III
Description: Count strobogrammatic numbers in range [low, high].
Java Solution:
public int strobogrammaticInRange(String low, String high) {
int count = 0;
for (int len = low.length(); len <= high.length(); len++) {
List<String> nums = findStrobogrammatic(len);
for (String num : nums) {
if ((len == low.length() && num.compareTo(low) < 0) ||
(len == high.length() && num.compareTo(high) > 0)) continue;
count++;
}
}
return count;
}
Explanation: Generate strobogrammatic numbers for each length in range. Filter those outside [low, high].
- Time Complexity: O(5^(n/2) × n)
- Space Complexity: O(5^(n/2))
249. Group Shifted Strings
Description: Group strings that can be shifted to each other.
Java Solution:
public List<List<String>> groupStrings(String[] strings) {
Map<String, List<String>> map = new HashMap<>();
for (String s : strings) {
String key = getKey(s);
map.computeIfAbsent(key, k -> new ArrayList<>()).add(s);
}
return new ArrayList<>(map.values());
}
private String getKey(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 1; i < s.length(); i++) {
int diff = s.charAt(i) - s.charAt(i - 1);
if (diff < 0) diff += 26;
sb.append(diff).append(",");
}
return sb.toString();
}
Explanation: Use relative differences between consecutive characters as key. Same differences = same shift group.
- Time Complexity: O(n × m)
- Space Complexity: O(n × m)
250. Count Univalue Subtrees
Description: Count subtrees where all nodes have same value.
Java Solution:
private int count = 0;
public int countUnivalSubtrees(TreeNode root) {
isUnivalue(root);
return count;
}
private boolean isUnivalue(TreeNode node) {
if (node == null) return true;
boolean left = isUnivalue(node.left);
boolean right = isUnivalue(node.right);
if (left && right) {
if (node.left != null && node.left.val != node.val) return false;
if (node.right != null && node.right.val != node.val) return false;
count++;
return true;
}
return false;
}
Explanation: Post-order traversal. Subtree is univalue if both children are univalue and have same value as parent.
- Time Complexity: O(n)
- Space Complexity: O(H)
251. Flatten 2D Vector
Description: Design an iterator to flatten a 2D vector. Implement the Vector2D class with next() and hasNext() methods.
Java Solution:
class Vector2D {
private int[][] vec;
private int row;
private int col;
public Vector2D(int[][] vec) {
this.vec = vec;
this.row = 0;
this.col = 0;
}
public int next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return vec[row][col++];
}
public boolean hasNext() {
while (row < vec.length) {
if (col < vec[row].length) {
return true;
}
row++;
col = 0;
}
return false;
}
}
Explanation: Uses two pointers to track current position in the 2D vector. The hasNext method advances to the next valid position by skipping empty rows.
- Time Complexity: O(1) amortized for both operations
- Space Complexity: O(1)
252. Meeting Rooms
Description: Given an array of meeting time intervals where intervals[i] = [start, end], determine if a person could attend all meetings (no overlapping meetings).
Java Solution:
public boolean canAttendMeetings(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] < intervals[i - 1][1]) {
return false;
}
}
return true;
}
Explanation: Sort meetings by start time and check if any meeting starts before the previous one ends. If so, there’s an overlap.
- Time Complexity: O(n log n)
- Space Complexity: O(1)
253. Meeting Rooms II
Description: Given an array of meeting time intervals, find the minimum number of conference rooms required.
Java Solution:
public int minMeetingRooms(int[][] intervals) {
if (intervals == null || intervals.length == 0) {
return 0;
}
int[] starts = new int[intervals.length];
int[] ends = new int[intervals.length];
for (int i = 0; i < intervals.length; i++) {
starts[i] = intervals[i][0];
ends[i] = intervals[i][1];
}
Arrays.sort(starts);
Arrays.sort(ends);
int rooms = 0;
int endIdx = 0;
for (int i = 0; i < starts.length; i++) {
if (starts[i] < ends[endIdx]) {
rooms++;
} else {
endIdx++;
}
}
return rooms;
}
Explanation: Separate start and end times, sort them independently. When a meeting starts before another ends, we need a new room. Otherwise, reuse a room.
- Time Complexity: O(n log n)
- Space Complexity: O(n)
254. Factor Combinations
Description: Write a function that takes an integer n and returns all possible combinations of its factors (excluding 1 and n itself).
Java Solution:
public List<List<Integer>> getFactors(int n) {
List<List<Integer>> result = new ArrayList<>();
backtrack(result, new ArrayList<>(), n, 2);
return result;
}
private void backtrack(List<List<Integer>> result, List<Integer> current, int n, int start) {
if (n == 1) {
if (current.size() > 1) {
result.add(new ArrayList<>(current));
}
return;
}
for (int i = start; i <= n; i++) {
if (n % i == 0) {
current.add(i);
backtrack(result, current, n / i, i);
current.remove(current.size() - 1);
}
}
}
Explanation: Uses backtracking to generate all factor combinations. Start from smallest factor and recursively find factors of quotient.
- Time Complexity: O(n log n)
- Space Complexity: O(log n)
255. Verify Preorder Sequence in Binary Search Tree
Description: Given an array of unique integers preorder, return true if it is the correct preorder traversal sequence of a binary search tree.
Java Solution:
public boolean verifyPreorder(int[] preorder) {
int low = Integer.MIN_VALUE;
Stack<Integer> stack = new Stack<>();
for (int num : preorder) {
if (num < low) {
return false;
}
while (!stack.isEmpty() && num > stack.peek()) {
low = stack.pop();
}
stack.push(num);
}
return true;
}
Explanation: Use a stack to track the path. When we find a larger value, pop smaller values (we’ve moved to right subtree) and update lower bound.
- Time Complexity: O(n)
- Space Complexity: O(n)
256. Paint House
Description: There are n houses in a row, each can be painted with red, blue, or green. Cost of painting each house with a certain color is different. Find the minimum cost to paint all houses such that no two adjacent houses have the same color.
Java Solution:
public int minCost(int[][] costs) {
if (costs == null || costs.length == 0) {
return 0;
}
int n = costs.length;
int[] dp = costs[0].clone();
for (int i = 1; i < n; i++) {
int prev0 = dp[0];
int prev1 = dp[1];
int prev2 = dp[2];
dp[0] = costs[i][0] + Math.min(prev1, prev2);
dp[1] = costs[i][1] + Math.min(prev0, prev2);
dp[2] = costs[i][2] + Math.min(prev0, prev1);
}
return Math.min(dp[0], Math.min(dp[1], dp[2]));
}
Explanation: Dynamic programming approach where dp[i] represents min cost to paint house i with each color. For each house, choose color with minimum cost from previous house’s other colors.
- Time Complexity: O(n)
- Space Complexity: O(1)
257. Binary Tree Paths
Description: Given the root of a binary tree, return all root-to-leaf paths in any order.
Java Solution:
public List<String> binaryTreePaths(TreeNode root) {
List<String> result = new ArrayList<>();
if (root == null) {
return result;
}
dfs(root, "", result);
return result;
}
private void dfs(TreeNode node, String path, List<String> result) {
if (node == null) {
return;
}
path += node.val;
if (node.left == null && node.right == null) {
result.add(path);
return;
}
path += "->";
dfs(node.left, path, result);
dfs(node.right, path, result);
}
Explanation: DFS traversal building path string as we go. When reaching a leaf node, add the complete path to results.
- Time Complexity: O(n)
- Space Complexity: O(h)
258. Add Digits
Description: Given an integer num, repeatedly add all its digits until the result has only one digit, and return it.
Java Solution:
public int addDigits(int num) {
if (num == 0) {
return 0;
}
return num % 9 == 0 ? 9 : num % 9;
}
Explanation: Uses digital root formula. The result is num % 9, except when num % 9 == 0 (and num != 0), the result is 9.
- Time Complexity: O(1)
- Space Complexity: O(1)
259. 3Sum Smaller
Description: Given an array of n integers nums and an integer target, find the number of index triplets i, j, k with 0 <= i < j < k < n that satisfy nums[i] + nums[j] + nums[k] < target.
Java Solution:
public int threeSumSmaller(int[] nums, int target) {
Arrays.sort(nums);
int count = 0;
for (int i = 0; i < nums.length - 2; i++) {
int left = i + 1;
int right = nums.length - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum < target) {
count += right - left;
left++;
} else {
right--;
}
}
}
return count;
}
Explanation: Sort array and use three pointers. For each fixed first element, use two pointers to find pairs. When sum is smaller than target, all elements between left and right form valid triplets.
- Time Complexity: O(n²)
- Space Complexity: O(1)
260. Single Number III
Description: Given an integer array nums where exactly two elements appear only once and all other elements appear exactly twice, find the two elements that appear only once.
Java Solution:
public int[] singleNumber(int[] nums) {
int xor = 0;
for (int num : nums) {
xor ^= num;
}
// Find rightmost set bit
int rightmostBit = xor & (-xor);
int[] result = new int[2];
for (int num : nums) {
if ((num & rightmostBit) == 0) {
result[0] ^= num;
} else {
result[1] ^= num;
}
}
return result;
}
Explanation: XOR all numbers to get XOR of the two unique numbers. Use any set bit to partition numbers into two groups, each containing one unique number.
- Time Complexity: O(n)
- Space Complexity: O(1)
261. Graph Valid Tree
Description: Given n nodes labeled from 0 to n-1 and a list of undirected edges, check if these edges form a valid tree.
Java Solution:
public boolean validTree(int n, int[][] edges) {
if (edges.length != n - 1) {
return false;
}
List<List<Integer>> graph = new ArrayList<>();
for (int i = 0; i < n; i++) {
graph.add(new ArrayList<>());
}
for (int[] edge : edges) {
graph.get(edge[0]).add(edge[1]);
graph.get(edge[1]).add(edge[0]);
}
boolean[] visited = new boolean[n];
if (!dfs(0, -1, graph, visited)) {
return false;
}
for (boolean v : visited) {
if (!v) {
return false;
}
}
return true;
}
private boolean dfs(int node, int parent, List<List<Integer>> graph, boolean[] visited) {
visited[node] = true;
for (int neighbor : graph.get(node)) {
if (neighbor == parent) {
continue;
}
if (visited[neighbor]) {
return false;
}
if (!dfs(neighbor, node, graph, visited)) {
return false;
}
}
return true;
}
Explanation: A valid tree must have exactly n-1 edges, be connected, and have no cycles. Use DFS to detect cycles and check connectivity.
- Time Complexity: O(n + e)
- Space Complexity: O(n + e)
262. Trips and Users
Description: SQL problem: Write a SQL query to find the cancellation rate of requests made by unbanned users between two dates.
Java Solution:
SELECT
request_at AS Day,
ROUND(
SUM(CASE WHEN status LIKE 'cancelled%' THEN 1 ELSE 0 END) / COUNT(*),
2
) AS 'Cancellation Rate'
FROM
Trips t
JOIN
Users u1 ON t.client_id = u1.users_id AND u1.banned = 'No'
JOIN
Users u2 ON t.driver_id = u2.users_id AND u2.banned = 'No'
WHERE
request_at BETWEEN '2013-10-01' AND '2013-10-03'
GROUP BY
request_at
Explanation: Join Trips with Users twice to filter out banned clients and drivers. Calculate cancellation rate by dividing cancelled trips by total trips for each day.
- Time Complexity: O(n)
- Space Complexity: O(1)
263. Ugly Number
Description: An ugly number is a positive integer whose prime factors are limited to 2, 3, and 5. Given an integer n, return true if n is an ugly number.
Java Solution:
public boolean isUgly(int n) {
if (n <= 0) {
return false;
}
while (n % 2 == 0) {
n /= 2;
}
while (n % 3 == 0) {
n /= 3;
}
while (n % 5 == 0) {
n /= 5;
}
return n == 1;
}
Explanation: Divide n by 2, 3, and 5 repeatedly. If the result is 1, then n only has these prime factors.
- Time Complexity: O(log n)
- Space Complexity: O(1)
264. Ugly Number II
Description: An ugly number is a positive integer whose prime factors are limited to 2, 3, and 5. Given an integer n, return the nth ugly number.
Java Solution:
public int nthUglyNumber(int n) {
int[] ugly = new int[n];
ugly[0] = 1;
int i2 = 0, i3 = 0, i5 = 0;
for (int i = 1; i < n; i++) {
int next2 = ugly[i2] * 2;
int next3 = ugly[i3] * 3;
int next5 = ugly[i5] * 5;
ugly[i] = Math.min(next2, Math.min(next3, next5));
if (ugly[i] == next2) i2++;
if (ugly[i] == next3) i3++;
if (ugly[i] == next5) i5++;
}
return ugly[n - 1];
}
Explanation: Use three pointers to track multiples of 2, 3, and 5. Generate ugly numbers in order by selecting the minimum next candidate.
- Time Complexity: O(n)
- Space Complexity: O(n)
265. Paint House II
Description: There are n houses and k colors. The cost of painting each house with a certain color is different. Find minimum cost to paint all houses such that no two adjacent houses have the same color.
Java Solution:
public int minCostII(int[][] costs) {
if (costs == null || costs.length == 0) {
return 0;
}
int n = costs.length;
int k = costs[0].length;
int[] dp = costs[0].clone();
for (int i = 1; i < n; i++) {
int[] newDp = new int[k];
int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
int minIdx = -1;
for (int j = 0; j < k; j++) {
if (dp[j] < min1) {
min2 = min1;
min1 = dp[j];
minIdx = j;
} else if (dp[j] < min2) {
min2 = dp[j];
}
}
for (int j = 0; j < k; j++) {
newDp[j] = costs[i][j] + (j == minIdx ? min2 : min1);
}
dp = newDp;
}
int result = Integer.MAX_VALUE;
for (int cost : dp) {
result = Math.min(result, cost);
}
return result;
}
Explanation: Track the two minimum costs from previous house. For each color, add current cost to the minimum that’s not the same color.
- Time Complexity: O(n * k)
- Space Complexity: O(k)
266. Palindrome Permutation
Description: Given a string s, return true if a permutation of the string could form a palindrome.
Java Solution:
public boolean canPermutePalindrome(String s) {
Map<Character, Integer> freq = new HashMap<>();
for (char c : s.toCharArray()) {
freq.put(c, freq.getOrDefault(c, 0) + 1);
}
int oddCount = 0;
for (int count : freq.values()) {
if (count % 2 == 1) {
oddCount++;
}
}
return oddCount <= 1;
}
Explanation: Count character frequencies. For a palindrome permutation to exist, at most one character can have an odd frequency.
- Time Complexity: O(n)
- Space Complexity: O(1)
267. Palindrome Permutation II
Description: Given a string s, return all the palindromic permutations (without duplicates) of it.
Java Solution:
public List<String> generatePalindromes(String s) {
List<String> result = new ArrayList<>();
Map<Character, Integer> freq = new HashMap<>();
for (char c : s.toCharArray()) {
freq.put(c, freq.getOrDefault(c, 0) + 1);
}
char oddChar = 0;
int oddCount = 0;
StringBuilder half = new StringBuilder();
for (Map.Entry<Character, Integer> entry : freq.entrySet()) {
char c = entry.getKey();
int count = entry.getValue();
if (count % 2 == 1) {
oddChar = c;
oddCount++;
}
for (int i = 0; i < count / 2; i++) {
half.append(c);
}
}
if (oddCount > 1) {
return result;
}
backtrack(result, half.toString().toCharArray(), 0, oddChar);
return result;
}
private void backtrack(List<String> result, char[] chars, int index, char oddChar) {
if (index == chars.length) {
String half = new String(chars);
String reversed = new StringBuilder(half).reverse().toString();
result.add(half + (oddChar == 0 ? "" : oddChar) + reversed);
return;
}
Set<Character> used = new HashSet<>();
for (int i = index; i < chars.length; i++) {
if (used.contains(chars[i])) {
continue;
}
used.add(chars[i]);
swap(chars, i, index);
backtrack(result, chars, index + 1, oddChar);
swap(chars, i, index);
}
}
private void swap(char[] chars, int i, int j) {
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
Explanation: Generate all permutations of half the string, then mirror it to create palindromes. Handle the odd character separately.
- Time Complexity: O(n!)
- Space Complexity: O(n)
268. Missing Number
Description: Given an array nums containing n distinct numbers in the range [0, n], return the only number in the range that is missing from the array.
Java Solution:
public int missingNumber(int[] nums) {
int n = nums.length;
int expectedSum = n * (n + 1) / 2;
int actualSum = 0;
for (int num : nums) {
actualSum += num;
}
return expectedSum - actualSum;
}
Explanation: Calculate the expected sum of numbers from 0 to n, then subtract the actual sum. The difference is the missing number.
- Time Complexity: O(n)
- Space Complexity: O(1)
269. Alien Dictionary
Description: Given a sorted dictionary of an alien language, derive the order of characters in this language.
Java Solution:
public String alienOrder(String[] words) {
Map<Character, Set<Character>> graph = new HashMap<>();
Map<Character, Integer> inDegree = new HashMap<>();
for (String word : words) {
for (char c : word.toCharArray()) {
graph.putIfAbsent(c, new HashSet<>());
inDegree.putIfAbsent(c, 0);
}
}
for (int i = 0; i < words.length - 1; i++) {
String word1 = words[i];
String word2 = words[i + 1];
int minLen = Math.min(word1.length(), word2.length());
if (word1.length() > word2.length() && word1.startsWith(word2)) {
return "";
}
for (int j = 0; j < minLen; j++) {
char c1 = word1.charAt(j);
char c2 = word2.charAt(j);
if (c1 != c2) {
if (!graph.get(c1).contains(c2)) {
graph.get(c1).add(c2);
inDegree.put(c2, inDegree.get(c2) + 1);
}
break;
}
}
}
Queue<Character> queue = new LinkedList<>();
for (char c : inDegree.keySet()) {
if (inDegree.get(c) == 0) {
queue.offer(c);
}
}
StringBuilder result = new StringBuilder();
while (!queue.isEmpty()) {
char c = queue.poll();
result.append(c);
for (char neighbor : graph.get(c)) {
inDegree.put(neighbor, inDegree.get(neighbor) - 1);
if (inDegree.get(neighbor) == 0) {
queue.offer(neighbor);
}
}
}
return result.length() == inDegree.size() ? result.toString() : "";
}
Explanation: Build a graph from character relationships in adjacent words, then perform topological sort using Kahn’s algorithm.
- Time Complexity: O(C)
- Space Complexity: O(1)
270. Closest Binary Search Tree Value
Description: Given the root of a binary search tree and a target value, return the value in the BST that is closest to the target.
Java Solution:
public int closestValue(TreeNode root, double target) {
int closest = root.val;
while (root != null) {
if (Math.abs(root.val - target) < Math.abs(closest - target)) {
closest = root.val;
}
if (target < root.val) {
root = root.left;
} else {
root = root.right;
}
}
return closest;
}
Explanation: Traverse BST like binary search, updating closest value when we find a node with smaller distance to target.
- Time Complexity: O(h)
- Space Complexity: O(1)
271. Encode and Decode Strings
Description: Design an algorithm to encode a list of strings to a single string and decode it back to the original list.
Java Solution:
public class Codec {
public String encode(List<String> strs) {
StringBuilder sb = new StringBuilder();
for (String str : strs) {
sb.append(str.length()).append('/').append(str);
}
return sb.toString();
}
public List<String> decode(String s) {
List<String> result = new ArrayList<>();
int i = 0;
while (i < s.length()) {
int slash = s.indexOf('/', i);
int len = Integer.parseInt(s.substring(i, slash));
String str = s.substring(slash + 1, slash + 1 + len);
result.add(str);
i = slash + 1 + len;
}
return result;
}
}
Explanation: Encode by prepending each string with its length followed by a delimiter. Decode by reading length, then extracting that many characters.
- Time Complexity: O(n)
- Space Complexity: O(n)
272. Closest Binary Search Tree Value II
Description: Given the root of a binary search tree, a target value, and an integer k, return the k values in the BST that are closest to the target.
Java Solution:
public List<Integer> closestKValues(TreeNode root, double target, int k) {
LinkedList<Integer> result = new LinkedList<>();
inorder(root, target, k, result);
return result;
}
private void inorder(TreeNode node, double target, int k, LinkedList<Integer> result) {
if (node == null) {
return;
}
inorder(node.left, target, k, result);
if (result.size() < k) {
result.add(node.val);
} else {
if (Math.abs(node.val - target) < Math.abs(result.getFirst() - target)) {
result.removeFirst();
result.add(node.val);
} else {
return;
}
}
inorder(node.right, target, k, result);
}
Explanation: Perform inorder traversal maintaining a window of k closest values. Use a deque to efficiently add/remove values.
- Time Complexity: O(n)
- Space Complexity: O(k)
273. Integer to English Words
Description: Convert a non-negative integer num to its English words representation.
Java Solution:
private final String[] LESS_THAN_20 = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
private final String[] TENS = {"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
private final String[] THOUSANDS = {"", "Thousand", "Million", "Billion"};
public String numberToWords(int num) {
if (num == 0) {
return "Zero";
}
int i = 0;
String words = "";
while (num > 0) {
if (num % 1000 != 0) {
words = helper(num % 1000) + THOUSANDS[i] + " " + words;
}
num /= 1000;
i++;
}
return words.trim();
}
private String helper(int num) {
if (num == 0) {
return "";
} else if (num < 20) {
return LESS_THAN_20[num] + " ";
} else if (num < 100) {
return TENS[num / 10] + " " + helper(num % 10);
} else {
return LESS_THAN_20[num / 100] + " Hundred " + helper(num % 100);
}
}
Explanation: Process number in groups of three digits. Use lookup tables for numbers under 20, tens, and thousand multipliers.
- Time Complexity: O(1)
- Space Complexity: O(1)
274. H-Index
Description: Given an array of integers citations where citations[i] is the number of citations a researcher received for their ith paper, return the researcher’s h-index.
Java Solution:
public int hIndex(int[] citations) {
Arrays.sort(citations);
int n = citations.length;
for (int i = 0; i < n; i++) {
int h = n - i;
if (citations[i] >= h) {
return h;
}
}
return 0;
}
Explanation: Sort citations in ascending order. H-index is the first position where citation count is greater than or equal to remaining papers.
- Time Complexity: O(n log n)
- Space Complexity: O(1)
275. H-Index II
Description: Given an array of integers citations where citations[i] is the number of citations a researcher received for their ith paper (sorted in ascending order), return the researcher’s h-index.
Java Solution:
public int hIndex(int[] citations) {
int n = citations.length;
int left = 0, right = n - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
int h = n - mid;
if (citations[mid] >= h) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return n - left;
}
Explanation: Use binary search since array is sorted. Find the first position where citation count >= number of remaining papers.
- Time Complexity: O(log n)
- Space Complexity: O(1)
276. Paint Fence
Description: You are painting a fence of n posts with k different colors. You must paint the posts following the rule: no more than two adjacent fence posts have the same color. Return the total number of ways you can paint the fence.
Java Solution:
public int numWays(int n, int k) {
if (n == 0) {
return 0;
}
if (n == 1) {
return k;
}
int same = k;
int diff = k * (k - 1);
for (int i = 3; i <= n; i++) {
int prevDiff = diff;
diff = (same + diff) * (k - 1);
same = prevDiff;
}
return same + diff;
}
Explanation: Track ways where last two posts are same color vs different. For each post, same = previous diff, diff = (previous same + diff) * (k-1).
- Time Complexity: O(n)
- Space Complexity: O(1)
277. Find the Celebrity
Description: Suppose you are at a party with n people labeled from 0 to n - 1. There is a celebrity at the party. A celebrity is someone who doesn’t know anyone but is known by everyone. Find the celebrity.
Java Solution:
public int findCelebrity(int n) {
int candidate = 0;
for (int i = 1; i < n; i++) {
if (knows(candidate, i)) {
candidate = i;
}
}
for (int i = 0; i < n; i++) {
if (i != candidate) {
if (knows(candidate, i) || !knows(i, candidate)) {
return -1;
}
}
}
return candidate;
}
Explanation: First pass finds candidate by eliminating non-celebrities. Second pass verifies candidate doesn’t know anyone and everyone knows them.
- Time Complexity: O(n)
- Space Complexity: O(1)
278. First Bad Version
Description: You are a product manager and currently leading a team to develop a new product. Since each version is developed based on the previous version, all the versions after a bad version are also bad. Find the first bad version.
Java Solution:
public int firstBadVersion(int n) {
int left = 1, right = n;
while (left < right) {
int mid = left + (right - left) / 2;
if (isBadVersion(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
Explanation: Use binary search to find the first bad version. If mid is bad, search left half; otherwise search right half.
- Time Complexity: O(log n)
- Space Complexity: O(1)
279. Perfect Squares
Description: Given an integer n, return the least number of perfect square numbers that sum to n.
Java Solution:
public int numSquares(int n) {
int[] dp = new int[n + 1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j * j <= i; j++) {
dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
}
}
return dp[n];
}
Explanation: Dynamic programming where dp[i] represents minimum squares needed for i. For each number, try all perfect squares less than or equal to it.
- Time Complexity: O(n * sqrt(n))
- Space Complexity: O(n)
280. Wiggle Sort
Description: Given an integer array nums, reorder it such that nums[0] <= nums[1] >= nums[2] <= nums[3]…
Java Solution:
public void wiggleSort(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
if ((i % 2 == 0 && nums[i] > nums[i + 1]) ||
(i % 2 == 1 && nums[i] < nums[i + 1])) {
swap(nums, i, i + 1);
}
}
}
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
Explanation: Iterate through array, swapping adjacent elements when they violate the wiggle pattern (even indices should be <= next, odd indices should be >= next).
- Time Complexity: O(n)
- Space Complexity: O(1)
281. Zigzag Iterator
Description: Given two 1D vectors, implement an iterator to return their elements alternately.
Java Solution:
public class ZigzagIterator {
private Queue<Iterator<Integer>> queue;
public ZigzagIterator(List<Integer> v1, List<Integer> v2) {
queue = new LinkedList<>();
if (!v1.isEmpty()) {
queue.offer(v1.iterator());
}
if (!v2.isEmpty()) {
queue.offer(v2.iterator());
}
}
public int next() {
Iterator<Integer> iter = queue.poll();
int result = iter.next();
if (iter.hasNext()) {
queue.offer(iter);
}
return result;
}
public boolean hasNext() {
return !queue.isEmpty();
}
}
Explanation: Use a queue of iterators. Poll an iterator, get next value, and re-add iterator to queue if it has more elements.
- Time Complexity: O(1) for both operations
- Space Complexity: O(k) where k is number of lists
282. Expression Add Operators
Description: Given a string num that contains only digits and an integer target, return all possibilities to insert the binary operators ’+’, ’-’, and ’*’ between the digits of num so that the resultant expression evaluates to the target value.
Java Solution:
public List<String> addOperators(String num, int target) {
List<String> result = new ArrayList<>();
backtrack(result, num, target, "", 0, 0, 0);
return result;
}
private void backtrack(List<String> result, String num, int target, String path, int pos, long eval, long mult) {
if (pos == num.length()) {
if (eval == target) {
result.add(path);
}
return;
}
for (int i = pos; i < num.length(); i++) {
if (i != pos && num.charAt(pos) == '0') {
break;
}
long curr = Long.parseLong(num.substring(pos, i + 1));
if (pos == 0) {
backtrack(result, num, target, path + curr, i + 1, curr, curr);
} else {
backtrack(result, num, target, path + "+" + curr, i + 1, eval + curr, curr);
backtrack(result, num, target, path + "-" + curr, i + 1, eval - curr, -curr);
backtrack(result, num, target, path + "*" + curr, i + 1, eval - mult + mult * curr, mult * curr);
}
}
}
Explanation: Use backtracking to try all operator combinations. Track current evaluation and last multiplied value for correct operator precedence.
- Time Complexity: O(4^n)
- Space Complexity: O(n)
283. Move Zeroes
Description: Given an integer array nums, move all 0’s to the end of it while maintaining the relative order of the non-zero elements.
Java Solution:
public void moveZeroes(int[] nums) {
int writeIdx = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != 0) {
nums[writeIdx++] = nums[i];
}
}
while (writeIdx < nums.length) {
nums[writeIdx++] = 0;
}
}
Explanation: Use two pointers: one to read non-zero values, one to write them. After copying non-zeros, fill remaining positions with zeros.
- Time Complexity: O(n)
- Space Complexity: O(1)
284. Peeking Iterator
Description: Design an iterator that supports the peek operation on an existing iterator in addition to hasNext and next.
Java Solution:
class PeekingIterator implements Iterator<Integer> {
private Iterator<Integer> iter;
private Integer peeked;
public PeekingIterator(Iterator<Integer> iterator) {
iter = iterator;
peeked = null;
}
public Integer peek() {
if (peeked == null) {
peeked = iter.next();
}
return peeked;
}
public Integer next() {
if (peeked != null) {
Integer result = peeked;
peeked = null;
return result;
}
return iter.next();
}
public boolean hasNext() {
return peeked != null || iter.hasNext();
}
}
Explanation: Cache the peeked value. On peek, fetch next from iterator if not cached. On next, return cached value or fetch new one.
- Time Complexity: O(1) for all operations
- Space Complexity: O(1)
285. Inorder Successor in BST
Description: Given the root of a binary search tree and a node p, return the in-order successor of that node in the BST.
Java Solution:
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
TreeNode successor = null;
while (root != null) {
if (p.val < root.val) {
successor = root;
root = root.left;
} else {
root = root.right;
}
}
return successor;
}
Explanation: Traverse BST like binary search. When going left, current node could be successor. The last such node is the answer.
- Time Complexity: O(h)
- Space Complexity: O(1)
286. Walls and Gates
Description: You are given an m x n grid rooms initialized with three possible values: -1 (wall), 0 (gate), or INF (empty room). Fill each empty room with the distance to its nearest gate.
Java Solution:
public void wallsAndGates(int[][] rooms) {
if (rooms == null || rooms.length == 0) {
return;
}
int m = rooms.length;
int n = rooms[0].length;
Queue<int[]> queue = new LinkedList<>();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (rooms[i][j] == 0) {
queue.offer(new int[]{i, j});
}
}
}
int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
while (!queue.isEmpty()) {
int[] cell = queue.poll();
int row = cell[0];
int col = cell[1];
for (int[] dir : dirs) {
int newRow = row + dir[0];
int newCol = col + dir[1];
if (newRow < 0 || newRow >= m || newCol < 0 || newCol >= n ||
rooms[newRow][newCol] != Integer.MAX_VALUE) {
continue;
}
rooms[newRow][newCol] = rooms[row][col] + 1;
queue.offer(new int[]{newRow, newCol});
}
}
}
Explanation: Multi-source BFS starting from all gates simultaneously. Each empty room gets distance from nearest gate.
- Time Complexity: O(m * n)
- Space Complexity: O(m * n)
287. Find the Duplicate Number
Description: Given an array of integers nums containing n + 1 integers where each integer is in the range [1, n] inclusive, there is only one repeated number. Return this repeated number.
Java Solution:
public int findDuplicate(int[] nums) {
int slow = nums[0];
int fast = nums[0];
do {
slow = nums[slow];
fast = nums[nums[fast]];
} while (slow != fast);
slow = nums[0];
while (slow != fast) {
slow = nums[slow];
fast = nums[fast];
}
return slow;
}
Explanation: Floyd’s cycle detection algorithm. Treat array as linked list where nums[i] points to index nums[i]. Find cycle entry point.
- Time Complexity: O(n)
- Space Complexity: O(1)
288. Unique Word Abbreviation
Description: The abbreviation of a word is a concatenation of its first letter, the number of characters between the first and last letter, and its last letter. Design a class that checks if an abbreviation is unique among a dictionary of words.
Java Solution:
class ValidWordAbbr {
private Map<String, Set<String>> abbrMap;
public ValidWordAbbr(String[] dictionary) {
abbrMap = new HashMap<>();
for (String word : dictionary) {
String abbr = getAbbr(word);
abbrMap.putIfAbsent(abbr, new HashSet<>());
abbrMap.get(abbr).add(word);
}
}
public boolean isUnique(String word) {
String abbr = getAbbr(word);
Set<String> words = abbrMap.get(abbr);
return words == null || (words.size() == 1 && words.contains(word));
}
private String getAbbr(String word) {
if (word.length() <= 2) {
return word;
}
return word.charAt(0) + String.valueOf(word.length() - 2) + word.charAt(word.length() - 1);
}
}
Explanation: Map abbreviations to sets of words with that abbreviation. An abbreviation is unique if only the query word has it.
- Time Complexity: O(n) for constructor, O(1) for isUnique
- Space Complexity: O(n)
289. Game of Life
Description: According to Wikipedia’s article: The Game of Life is a cellular automaton devised by the British mathematician John Horton Conway in 1970. The board is made up of an m x n grid of cells. Given the current state of the board, update the board to reflect its next state.
Java Solution:
public void gameOfLife(int[][] board) {
int m = board.length;
int n = board[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int lives = countLiveNeighbors(board, i, j, m, n);
if (board[i][j] == 1) {
if (lives == 2 || lives == 3) {
board[i][j] = 3; // 1 -> 1
}
} else {
if (lives == 3) {
board[i][j] = 2; // 0 -> 1
}
}
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
board[i][j] >>= 1;
}
}
}
private int countLiveNeighbors(int[][] board, int row, int col, int m, int n) {
int lives = 0;
for (int i = Math.max(row - 1, 0); i <= Math.min(row + 1, m - 1); i++) {
for (int j = Math.max(col - 1, 0); j <= Math.min(col + 1, n - 1); j++) {
lives += board[i][j] & 1;
}
}
lives -= board[row][col] & 1;
return lives;
}
Explanation: Use bit manipulation to store both current and next state. Least significant bit is current state, next bit is next state. Count neighbors using current state only.
- Time Complexity: O(m * n)
- Space Complexity: O(1)
290. Word Pattern
Description: Given a pattern and a string s, find if s follows the same pattern. Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in s.
Java Solution:
public boolean wordPattern(String pattern, String s) {
String[] words = s.split(" ");
if (pattern.length() != words.length) {
return false;
}
Map<Character, String> charToWord = new HashMap<>();
Map<String, Character> wordToChar = new HashMap<>();
for (int i = 0; i < pattern.length(); i++) {
char c = pattern.charAt(i);
String word = words[i];
if (charToWord.containsKey(c)) {
if (!charToWord.get(c).equals(word)) {
return false;
}
} else {
charToWord.put(c, word);
}
if (wordToChar.containsKey(word)) {
if (wordToChar.get(word) != c) {
return false;
}
} else {
wordToChar.put(word, c);
}
}
return true;
}
Explanation: Use two hash maps to track bidirectional mapping between pattern characters and words. Both mappings must be consistent.
- Time Complexity: O(n)
- Space Complexity: O(n)
291. Word Pattern II
Description: Given a pattern and a string s, return true if s matches the pattern. A string matches the pattern if there is a bijection between a letter in pattern and a non-empty substring in s.
Java Solution:
public boolean wordPatternMatch(String pattern, String s) {
return backtrack(pattern, s, 0, 0, new HashMap<>(), new HashSet<>());
}
private boolean backtrack(String pattern, String s, int i, int j, Map<Character, String> map, Set<String> used) {
if (i == pattern.length() && j == s.length()) {
return true;
}
if (i == pattern.length() || j == s.length()) {
return false;
}
char c = pattern.charAt(i);
if (map.containsKey(c)) {
String word = map.get(c);
if (!s.startsWith(word, j)) {
return false;
}
return backtrack(pattern, s, i + 1, j + word.length(), map, used);
}
for (int k = j; k < s.length(); k++) {
String word = s.substring(j, k + 1);
if (used.contains(word)) {
continue;
}
map.put(c, word);
used.add(word);
if (backtrack(pattern, s, i + 1, k + 1, map, used)) {
return true;
}
map.remove(c);
used.remove(word);
}
return false;
}
Explanation: Use backtracking with hash map for pattern-to-word mapping and set for used words. Try all possible word lengths for each pattern character.
- Time Complexity: O(n^m)
- Space Complexity: O(m)
292. Nim Game
Description: You are playing a Nim Game with a friend where you take turns removing 1 to 3 stones from a pile. The player who removes the last stone wins. Given n, the number of stones in the pile, return true if you can win the game assuming both you and your friend play optimally.
Java Solution:
public boolean canWinNim(int n) {
return n % 4 != 0;
}
Explanation: If there are 4 stones, you lose regardless of your move. With any other number, you can force opponent into the losing position by leaving them with a multiple of 4.
- Time Complexity: O(1)
- Space Complexity: O(1)
293. Flip Game
Description: You are playing a Flip Game with your friend. You are given a string currentState that contains only ’+’ and ’-’. You and your friend take turns to flip two consecutive ”++” into ”—”. Return all possible states of the string after one valid move.
Java Solution:
public List<String> generatePossibleNextMoves(String currentState) {
List<String> result = new ArrayList<>();
for (int i = 0; i < currentState.length() - 1; i++) {
if (currentState.charAt(i) == '+' && currentState.charAt(i + 1) == '+') {
result.add(currentState.substring(0, i) + "--" + currentState.substring(i + 2));
}
}
return result;
}
Explanation: Scan through string looking for consecutive ’++’ and flip them to ’—’, generating all possible next states.
- Time Complexity: O(n²)
- Space Complexity: O(n)
294. Flip Game II
Description: You are playing a Flip Game with your friend. The rules are the same as Flip Game, but you need to determine if the starting player can guarantee a win.
Java Solution:
public boolean canWin(String currentState) {
for (int i = 0; i < currentState.length() - 1; i++) {
if (currentState.charAt(i) == '+' && currentState.charAt(i + 1) == '+') {
String next = currentState.substring(0, i) + "--" + currentState.substring(i + 2);
if (!canWin(next)) {
return true;
}
}
}
return false;
}
Explanation: Try all possible moves. If any move leads to a state where opponent cannot win, current player can guarantee a win.
- Time Complexity: O(n!!)
- Space Complexity: O(n)
295. Find Median from Data Stream
Description: The median is the middle value in an ordered integer list. Design a data structure that supports adding integers and finding the median.
Java Solution:
class MedianFinder {
private PriorityQueue<Integer> maxHeap;
private PriorityQueue<Integer> minHeap;
public MedianFinder() {
maxHeap = new PriorityQueue<>(Collections.reverseOrder());
minHeap = new PriorityQueue<>();
}
public void addNum(int num) {
maxHeap.offer(num);
minHeap.offer(maxHeap.poll());
if (minHeap.size() > maxHeap.size()) {
maxHeap.offer(minHeap.poll());
}
}
public double findMedian() {
if (maxHeap.size() > minHeap.size()) {
return maxHeap.peek();
}
return (maxHeap.peek() + minHeap.peek()) / 2.0;
}
}
Explanation: Use two heaps: max heap for smaller half, min heap for larger half. Balance heaps to keep size difference at most 1. Median is from heap tops.
- Time Complexity: O(log n) for add, O(1) for findMedian
- Space Complexity: O(n)
296. Best Meeting Point
Description: Given an m x n binary grid grid where each 1 marks the home of one friend, return the minimal total travel distance. The total travel distance is the sum of the distances between the houses of the friends and the meeting point.
Java Solution:
public int minTotalDistance(int[][] grid) {
List<Integer> rows = new ArrayList<>();
List<Integer> cols = new ArrayList<>();
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
rows.add(i);
cols.add(j);
}
}
}
Collections.sort(cols);
int rowMedian = rows.get(rows.size() / 2);
int colMedian = cols.get(cols.size() / 2);
return calculateDistance(rows, rowMedian) + calculateDistance(cols, colMedian);
}
private int calculateDistance(List<Integer> points, int median) {
int distance = 0;
for (int point : points) {
distance += Math.abs(point - median);
}
return distance;
}
Explanation: Optimal meeting point is at median of all row coordinates and median of all column coordinates. Calculate Manhattan distance from median.
- Time Complexity: O(m * n log n)
- Space Complexity: O(m * n)
297. Serialize and Deserialize Binary Tree
Description: Design an algorithm to serialize and deserialize a binary tree. Serialization is converting a tree to a string, and deserialization is converting the string back to the tree structure.
Java Solution:
public class Codec {
public String serialize(TreeNode root) {
if (root == null) {
return "null";
}
return root.val + "," + serialize(root.left) + "," + serialize(root.right);
}
public TreeNode deserialize(String data) {
Queue<String> queue = new LinkedList<>(Arrays.asList(data.split(",")));
return helper(queue);
}
private TreeNode helper(Queue<String> queue) {
String val = queue.poll();
if (val.equals("null")) {
return null;
}
TreeNode node = new TreeNode(Integer.parseInt(val));
node.left = helper(queue);
node.right = helper(queue);
return node;
}
}
Explanation: Use preorder traversal for serialization with null markers. For deserialization, recursively build tree using queue of values.
- Time Complexity: O(n)
- Space Complexity: O(n)
298. Binary Tree Longest Consecutive Sequence
Description: Given the root of a binary tree, return the length of the longest consecutive sequence path. The path must go from parent to child (cannot go from child to parent).
Java Solution:
public int longestConsecutive(TreeNode root) {
return dfs(root, null, 0);
}
private int dfs(TreeNode node, TreeNode parent, int length) {
if (node == null) {
return length;
}
int currentLength = (parent != null && node.val == parent.val + 1) ? length + 1 : 1;
return Math.max(currentLength,
Math.max(dfs(node.left, node, currentLength),
dfs(node.right, node, currentLength)));
}
Explanation: DFS traversal tracking current consecutive length. Reset to 1 when sequence breaks, increment when it continues.
- Time Complexity: O(n)
- Space Complexity: O(h)
299. Bulls and Cows
Description: You are playing the Bulls and Cows game. Your friend thinks of a number and asks you to guess it. Each time you make a guess, your friend provides a hint with bulls (correct digits in correct positions) and cows (correct digits in wrong positions).
Java Solution:
public String getHint(String secret, String guess) {
int bulls = 0;
int cows = 0;
int[] secretCounts = new int[10];
int[] guessCounts = new int[10];
for (int i = 0; i < secret.length(); i++) {
if (secret.charAt(i) == guess.charAt(i)) {
bulls++;
} else {
secretCounts[secret.charAt(i) - '0']++;
guessCounts[guess.charAt(i) - '0']++;
}
}
for (int i = 0; i < 10; i++) {
cows += Math.min(secretCounts[i], guessCounts[i]);
}
return bulls + "A" + cows + "B";
}
Explanation: Count bulls in first pass. Track digit frequencies for non-bulls. Cows are minimum of secret and guess frequencies for each digit.
- Time Complexity: O(n)
- Space Complexity: O(1)
300. Longest Increasing Subsequence
Description: Given an integer array nums, return the length of the longest strictly increasing subsequence.
Java Solution:
public int lengthOfLIS(int[] nums) {
int[] dp = new int[nums.length];
int len = 0;
for (int num : nums) {
int i = Arrays.binarySearch(dp, 0, len, num);
if (i < 0) {
i = -(i + 1);
}
dp[i] = num;
if (i == len) {
len++;
}
}
return len;
}
Explanation: Maintain array of smallest tail elements for all increasing subsequences of each length. Use binary search to find position for each element.
- Time Complexity: O(n log n)
- Space Complexity: O(n)
301. Remove Invalid Parentheses
Description: Given a string s that contains parentheses and letters, remove the minimum number of invalid parentheses to make the input string valid. Return all possible results.
Java Solution:
public List<String> removeInvalidParentheses(String s) {
List<String> result = new ArrayList<>();
if (s == null) {
return result;
}
Set<String> visited = new HashSet<>();
Queue<String> queue = new LinkedList<>();
queue.offer(s);
visited.add(s);
boolean found = false;
while (!queue.isEmpty()) {
String str = queue.poll();
if (isValid(str)) {
result.add(str);
found = true;
}
if (found) {
continue;
}
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) != '(' && str.charAt(i) != ')') {
continue;
}
String next = str.substring(0, i) + str.substring(i + 1);
if (!visited.contains(next)) {
visited.add(next);
queue.offer(next);
}
}
}
return result;
}
private boolean isValid(String s) {
int count = 0;
for (char c : s.toCharArray()) {
if (c == '(') {
count++;
} else if (c == ')') {
count--;
if (count < 0) {
return false;
}
}
}
return count == 0;
}
Explanation: Use BFS to try removing each parenthesis. First level where valid strings are found contains minimum removals.
- Time Complexity: O(2^n)
- Space Complexity: O(2^n)
302. Smallest Rectangle Enclosing Black Pixels
Description: An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. Given the location (x, y) of one of the black pixels, return the area of the smallest rectangle that encloses all black pixels.
Java Solution:
public int minArea(char[][] image, int x, int y) {
int m = image.length;
int n = image[0].length;
int left = searchColumns(image, 0, y, 0, m, true);
int right = searchColumns(image, y + 1, n, 0, m, false);
int top = searchRows(image, 0, x, left, right, true);
int bottom = searchRows(image, x + 1, m, left, right, false);
return (right - left) * (bottom - top);
}
private int searchColumns(char[][] image, int i, int j, int top, int bottom, boolean opt) {
while (i != j) {
int k = top;
int mid = (i + j) / 2;
while (k < bottom && image[k][mid] == '0') {
k++;
}
if (k < bottom == opt) {
j = mid;
} else {
i = mid + 1;
}
}
return i;
}
private int searchRows(char[][] image, int i, int j, int left, int right, boolean opt) {
while (i != j) {
int k = left;
int mid = (i + j) / 2;
while (k < right && image[mid][k] == '0') {
k++;
}
if (k < right == opt) {
j = mid;
} else {
i = mid + 1;
}
}
return i;
}
Explanation: Use binary search to find boundaries. Since all black pixels are connected, we can binary search for leftmost, rightmost, topmost, and bottommost black pixels.
- Time Complexity: O(m log n + n log m)
- Space Complexity: O(1)
303. Range Sum Query - Immutable
Description: Given an integer array nums, handle multiple queries to calculate the sum of the elements of nums between indices left and right.
Java Solution:
class NumArray {
private int[] prefixSum;
public NumArray(int[] nums) {
prefixSum = new int[nums.length + 1];
for (int i = 0; i < nums.length; i++) {
prefixSum[i + 1] = prefixSum[i] + nums[i];
}
}
public int sumRange(int left, int right) {
return prefixSum[right + 1] - prefixSum[left];
}
}
Explanation: Build prefix sum array where prefixSum[i] = sum of first i elements. Range sum is difference of prefix sums.
- Time Complexity: O(1) for sumRange, O(n) for constructor
- Space Complexity: O(n)
304. Range Sum Query 2D - Immutable
Description: Given a 2D matrix matrix, handle multiple queries to calculate the sum of the elements inside the rectangle defined by its upper left corner (row1, col1) and lower right corner (row2, col2).
Java Solution:
class NumMatrix {
private int[][] prefixSum;
public NumMatrix(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return;
}
int m = matrix.length;
int n = matrix[0].length;
prefixSum = new int[m + 1][n + 1];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
prefixSum[i][j] = matrix[i - 1][j - 1] +
prefixSum[i - 1][j] +
prefixSum[i][j - 1] -
prefixSum[i - 1][j - 1];
}
}
}
public int sumRegion(int row1, int col1, int row2, int col2) {
return prefixSum[row2 + 1][col2 + 1] -
prefixSum[row1][col2 + 1] -
prefixSum[row2 + 1][col1] +
prefixSum[row1][col1];
}
}
Explanation: Build 2D prefix sum array. Use inclusion-exclusion principle to calculate rectangle sum from four prefix sum lookups.
- Time Complexity: O(1) for sumRegion, O(m * n) for constructor
- Space Complexity: O(m * n)
305. Number of Islands II
Description: You are given an empty 2D binary grid grid of size m x n. Initially, all cells are water. We can perform operations to turn water into land. Return the number of islands after each operation.
Java Solution:
public List<Integer> numIslands2(int m, int n, int[][] positions) {
List<Integer> result = new ArrayList<>();
int[] parent = new int[m * n];
Arrays.fill(parent, -1);
int count = 0;
int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
for (int[] pos : positions) {
int r = pos[0];
int c = pos[1];
int idx = r * n + c;
if (parent[idx] != -1) {
result.add(count);
continue;
}
parent[idx] = idx;
count++;
for (int[] dir : dirs) {
int newR = r + dir[0];
int newC = c + dir[1];
int newIdx = newR * n + newC;
if (newR < 0 || newR >= m || newC < 0 || newC >= n || parent[newIdx] == -1) {
continue;
}
int root1 = find(parent, idx);
int root2 = find(parent, newIdx);
if (root1 != root2) {
parent[root1] = root2;
count--;
}
}
result.add(count);
}
return result;
}
private int find(int[] parent, int x) {
if (parent[x] != x) {
parent[x] = find(parent, parent[x]);
}
return parent[x];
}
Explanation: Use Union-Find to track connected components. For each new land, check adjacent cells and merge islands if they connect.
- Time Complexity: O(k * α(m*n)) where k is number of operations
- Space Complexity: O(m * n)
306. Additive Number
Description: An additive number is a string whose digits can form an additive sequence. Return true if the string is an additive number.
Java Solution:
public boolean isAdditiveNumber(String num) {
int n = num.length();
for (int i = 1; i <= n / 2; i++) {
if (num.charAt(0) == '0' && i > 1) {
break;
}
long num1 = Long.parseLong(num.substring(0, i));
for (int j = i + 1; n - j >= Math.max(i, j - i); j++) {
if (num.charAt(i) == '0' && j > i + 1) {
break;
}
long num2 = Long.parseLong(num.substring(i, j));
if (isValid(num, j, num1, num2)) {
return true;
}
}
}
return false;
}
private boolean isValid(String num, int start, long num1, long num2) {
if (start == num.length()) {
return true;
}
long sum = num1 + num2;
String sumStr = String.valueOf(sum);
if (!num.startsWith(sumStr, start)) {
return false;
}
return isValid(num, start + sumStr.length(), num2, sum);
}
Explanation: Try all possible first two numbers, then validate if rest of string follows additive pattern.
- Time Complexity: O(n³)
- Space Complexity: O(n)
307. Range Sum Query - Mutable
Description: Given an integer array nums, handle multiple queries to update the value of an element and calculate the sum of elements between indices left and right.
Java Solution:
class NumArray {
private int[] tree;
private int n;
public NumArray(int[] nums) {
n = nums.length;
tree = new int[n * 2];
for (int i = 0; i < n; i++) {
tree[n + i] = nums[i];
}
for (int i = n - 1; i > 0; i--) {
tree[i] = tree[i * 2] + tree[i * 2 + 1];
}
}
public void update(int index, int val) {
index += n;
tree[index] = val;
while (index > 1) {
tree[index / 2] = tree[index] + tree[index ^ 1];
index /= 2;
}
}
public int sumRange(int left, int right) {
left += n;
right += n;
int sum = 0;
while (left <= right) {
if ((left % 2) == 1) {
sum += tree[left++];
}
if ((right % 2) == 0) {
sum += tree[right--];
}
left /= 2;
right /= 2;
}
return sum;
}
}
Explanation: Use segment tree for efficient range queries and updates. Tree array stores interval sums at each node.
- Time Complexity: O(log n) for both operations
- Space Complexity: O(n)
308. Range Sum Query 2D - Mutable
Description: Given a 2D matrix matrix, handle multiple queries to update the value of a cell and calculate the sum of elements inside a rectangle.
Java Solution:
class NumMatrix {
private int[][] tree;
private int[][] nums;
private int m;
private int n;
public NumMatrix(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return;
}
m = matrix.length;
n = matrix[0].length;
tree = new int[m + 1][n + 1];
nums = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
update(i, j, matrix[i][j]);
}
}
}
public void update(int row, int col, int val) {
if (m == 0 || n == 0) {
return;
}
int delta = val - nums[row][col];
nums[row][col] = val;
for (int i = row + 1; i <= m; i += i & (-i)) {
for (int j = col + 1; j <= n; j += j & (-j)) {
tree[i][j] += delta;
}
}
}
public int sumRegion(int row1, int col1, int row2, int col2) {
return sum(row2, col2) - sum(row1 - 1, col2) - sum(row2, col1 - 1) + sum(row1 - 1, col1 - 1);
}
private int sum(int row, int col) {
int sum = 0;
for (int i = row + 1; i > 0; i -= i & (-i)) {
for (int j = col + 1; j > 0; j -= j & (-j)) {
sum += tree[i][j];
}
}
return sum;
}
}
Explanation: Use 2D Binary Indexed Tree (Fenwick Tree) for efficient updates and range queries in 2D.
- Time Complexity: O(log m * log n) for both operations
- Space Complexity: O(m * n)
309. Best Time to Buy and Sell Stock with Cooldown
Description: You are given an array prices where prices[i] is the price of a given stock on the ith day. After you sell your stock, you cannot buy stock on the next day (cooldown one day). Find the maximum profit you can achieve.
Java Solution:
public int maxProfit(int[] prices) {
if (prices == null || prices.length <= 1) {
return 0;
}
int sold = 0;
int held = -prices[0];
int reset = 0;
for (int i = 1; i < prices.length; i++) {
int prevSold = sold;
sold = held + prices[i];
held = Math.max(held, reset - prices[i]);
reset = Math.max(reset, prevSold);
}
return Math.max(sold, reset);
}
Explanation: Track three states: sold (just sold), held (holding stock), reset (cooldown). Transition between states based on actions.
- Time Complexity: O(n)
- Space Complexity: O(1)
310. Minimum Height Trees
Description: A tree is an undirected graph in which any two vertices are connected by exactly one path. Given a tree of n nodes labelled from 0 to n - 1, return a list of all Minimum Height Trees root labels.
Java Solution:
public List<Integer> findMinHeightTrees(int n, int[][] edges) {
if (n == 1) {
return Collections.singletonList(0);
}
List<Set<Integer>> graph = new ArrayList<>();
for (int i = 0; i < n; i++) {
graph.add(new HashSet<>());
}
for (int[] edge : edges) {
graph.get(edge[0]).add(edge[1]);
graph.get(edge[1]).add(edge[0]);
}
List<Integer> leaves = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (graph.get(i).size() == 1) {
leaves.add(i);
}
}
int remaining = n;
while (remaining > 2) {
remaining -= leaves.size();
List<Integer> newLeaves = new ArrayList<>();
for (int leaf : leaves) {
int neighbor = graph.get(leaf).iterator().next();
graph.get(neighbor).remove(leaf);
if (graph.get(neighbor).size() == 1) {
newLeaves.add(neighbor);
}
}
leaves = newLeaves;
}
return leaves;
}
Explanation: Peel off leaf nodes layer by layer like peeling an onion. The last 1 or 2 nodes remaining are the roots of minimum height trees.
- Time Complexity: O(n)
- Space Complexity: O(n)
311. Sparse Matrix Multiplication
Description: Given two sparse matrices mat1 and mat2, return the result of mat1 x mat2. You may assume that multiplication is always valid.
Java Solution:
public int[][] multiply(int[][] mat1, int[][] mat2) {
int m = mat1.length;
int k = mat1[0].length;
int n = mat2[0].length;
int[][] result = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < k; j++) {
if (mat1[i][j] != 0) {
for (int l = 0; l < n; l++) {
if (mat2[j][l] != 0) {
result[i][l] += mat1[i][j] * mat2[j][l];
}
}
}
}
}
return result;
}
Explanation: Skip zero elements in sparse matrices to optimize multiplication. Only multiply when both values are non-zero.
- Time Complexity: O(m * k * n) worst case, faster for sparse
- Space Complexity: O(m * n)
312. Burst Balloons
Description: You are given n balloons indexed from 0 to n - 1. Each balloon is painted with a number on it. You are asked to burst all the balloons. If you burst balloon i, you will get nums[i - 1] * nums[i] * nums[i + 1] coins. Return the maximum coins you can collect.
Java Solution:
public int maxCoins(int[] nums) {
int n = nums.length;
int[] arr = new int[n + 2];
arr[0] = arr[n + 1] = 1;
for (int i = 0; i < n; i++) {
arr[i + 1] = nums[i];
}
int[][] dp = new int[n + 2][n + 2];
for (int len = 1; len <= n; len++) {
for (int left = 1; left <= n - len + 1; left++) {
int right = left + len - 1;
for (int i = left; i <= right; i++) {
dp[left][right] = Math.max(dp[left][right],
arr[left - 1] * arr[i] * arr[right + 1] +
dp[left][i - 1] + dp[i + 1][right]);
}
}
}
return dp[1][n];
}
Explanation: Think backwards: choose the last balloon to burst. Use DP where dp[i][j] is max coins from bursting balloons i to j.
- Time Complexity: O(n³)
- Space Complexity: O(n²)
313. Super Ugly Number
Description: A super ugly number is a positive integer whose prime factors are in the array primes. Given an integer n and an array of integers primes, return the nth super ugly number.
Java Solution:
public int nthSuperUglyNumber(int n, int[] primes) {
int[] ugly = new int[n];
int[] indices = new int[primes.length];
ugly[0] = 1;
for (int i = 1; i < n; i++) {
int min = Integer.MAX_VALUE;
for (int j = 0; j < primes.length; j++) {
min = Math.min(min, ugly[indices[j]] * primes[j]);
}
ugly[i] = min;
for (int j = 0; j < primes.length; j++) {
if (ugly[indices[j]] * primes[j] == min) {
indices[j]++;
}
}
}
return ugly[n - 1];
}
Explanation: Similar to Ugly Number II but with multiple prime factors. Track index for each prime and choose minimum candidate.
- Time Complexity: O(n * k) where k is number of primes
- Space Complexity: O(n + k)
314. Binary Tree Vertical Order Traversal
Description: Given the root of a binary tree, return the vertical order traversal of its nodes’ values from left to right.
Java Solution:
public List<List<Integer>> verticalOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) {
return result;
}
Map<Integer, List<Integer>> map = new HashMap<>();
Queue<TreeNode> nodeQueue = new LinkedList<>();
Queue<Integer> colQueue = new LinkedList<>();
nodeQueue.offer(root);
colQueue.offer(0);
int minCol = 0;
int maxCol = 0;
while (!nodeQueue.isEmpty()) {
TreeNode node = nodeQueue.poll();
int col = colQueue.poll();
map.putIfAbsent(col, new ArrayList<>());
map.get(col).add(node.val);
if (node.left != null) {
nodeQueue.offer(node.left);
colQueue.offer(col - 1);
minCol = Math.min(minCol, col - 1);
}
if (node.right != null) {
nodeQueue.offer(node.right);
colQueue.offer(col + 1);
maxCol = Math.max(maxCol, col + 1);
}
}
for (int i = minCol; i <= maxCol; i++) {
result.add(map.get(i));
}
return result;
}
Explanation: Use BFS with column tracking. Map each column to its nodes. Process from leftmost to rightmost column.
- Time Complexity: O(n)
- Space Complexity: O(n)
315. Count of Smaller Numbers After Self
Description: Given an integer array nums, return an integer array counts where counts[i] is the number of smaller elements to the right of nums[i].
Java Solution:
public List<Integer> countSmaller(int[] nums) {
int n = nums.length;
int[] result = new int[n];
int[] indices = new int[n];
for (int i = 0; i < n; i++) {
indices[i] = i;
}
mergeSort(nums, indices, result, 0, n - 1);
List<Integer> list = new ArrayList<>();
for (int count : result) {
list.add(count);
}
return list;
}
private void mergeSort(int[] nums, int[] indices, int[] result, int left, int right) {
if (left >= right) {
return;
}
int mid = left + (right - left) / 2;
mergeSort(nums, indices, result, left, mid);
mergeSort(nums, indices, result, mid + 1, right);
merge(nums, indices, result, left, mid, right);
}
private void merge(int[] nums, int[] indices, int[] result, int left, int mid, int right) {
int[] temp = new int[right - left + 1];
int i = left;
int j = mid + 1;
int k = 0;
int rightCount = 0;
while (i <= mid && j <= right) {
if (nums[indices[j]] < nums[indices[i]]) {
temp[k++] = indices[j++];
rightCount++;
} else {
result[indices[i]] += rightCount;
temp[k++] = indices[i++];
}
}
while (i <= mid) {
result[indices[i]] += rightCount;
temp[k++] = indices[i++];
}
while (j <= right) {
temp[k++] = indices[j++];
}
System.arraycopy(temp, 0, indices, left, temp.length);
}
Explanation: Use merge sort with index tracking. During merge, count how many elements from right part come before each element from left part.
- Time Complexity: O(n log n)
- Space Complexity: O(n)
316. Remove Duplicate Letters
Description: Given a string s, remove duplicate letters so that every letter appears once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.
Java Solution:
public String removeDuplicateLetters(String s) {
int[] count = new int[26];
boolean[] visited = new boolean[26];
for (char c : s.toCharArray()) {
count[c - 'a']++;
}
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
count[c - 'a']--;
if (visited[c - 'a']) {
continue;
}
while (!stack.isEmpty() && stack.peek() > c && count[stack.peek() - 'a'] > 0) {
visited[stack.pop() - 'a'] = false;
}
stack.push(c);
visited[c - 'a'] = true;
}
StringBuilder result = new StringBuilder();
for (char c : stack) {
result.append(c);
}
return result.toString();
}
Explanation: Use stack to build result. Pop larger characters if they appear later. Track visited characters and remaining counts.
- Time Complexity: O(n)
- Space Complexity: O(1)
317. Shortest Distance from All Buildings
Description: You are given an m x n grid grid where each cell is either a building (1), an obstacle (2), or empty land (0). Find the shortest distance such that you can build one house such that the total distance to all buildings is minimized.
Java Solution:
public int shortestDistance(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int[][] distance = new int[m][n];
int[][] reach = new int[m][n];
int buildings = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
buildings++;
bfs(grid, i, j, distance, reach);
}
}
}
int minDistance = Integer.MAX_VALUE;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 0 && reach[i][j] == buildings) {
minDistance = Math.min(minDistance, distance[i][j]);
}
}
}
return minDistance == Integer.MAX_VALUE ? -1 : minDistance;
}
private void bfs(int[][] grid, int row, int col, int[][] distance, int[][] reach) {
int m = grid.length;
int n = grid[0].length;
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{row, col});
boolean[][] visited = new boolean[m][n];
visited[row][col] = true;
int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int level = 0;
while (!queue.isEmpty()) {
int size = queue.size();
level++;
for (int i = 0; i < size; i++) {
int[] cell = queue.poll();
int r = cell[0];
int c = cell[1];
for (int[] dir : dirs) {
int newR = r + dir[0];
int newC = c + dir[1];
if (newR >= 0 && newR < m && newC >= 0 && newC < n &&
!visited[newR][newC] && grid[newR][newC] == 0) {
distance[newR][newC] += level;
reach[newR][newC]++;
visited[newR][newC] = true;
queue.offer(new int[]{newR, newC});
}
}
}
}
}
Explanation: BFS from each building to calculate distances to all empty lands. Find empty land that can reach all buildings with minimum total distance.
- Time Complexity: O(m² * n² * k) where k is number of buildings
- Space Complexity: O(m * n)
318. Maximum Product of Word Lengths
Description: Given a string array words, return the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters.
Java Solution:
public int maxProduct(String[] words) {
int n = words.length;
int[] masks = new int[n];
for (int i = 0; i < n; i++) {
for (char c : words[i].toCharArray()) {
masks[i] |= 1 << (c - 'a');
}
}
int maxProduct = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if ((masks[i] & masks[j]) == 0) {
maxProduct = Math.max(maxProduct, words[i].length() * words[j].length());
}
}
}
return maxProduct;
}
Explanation: Use bit mask to represent character set for each word. Two words share no letters if their masks AND to 0.
- Time Complexity: O(n² + L) where L is total length of all words
- Space Complexity: O(n)
319. Bulb Switcher
Description: There are n bulbs initially off. You first turn on all the bulbs, then turn off every second bulb, then toggle every third bulb, and so on. After n rounds, return how many bulbs are on.
Java Solution:
public int bulbSwitch(int n) {
return (int) Math.sqrt(n);
}
Explanation: A bulb is toggled once for each of its divisors. Only perfect squares have an odd number of divisors, so only they remain on.
- Time Complexity: O(1)
- Space Complexity: O(1)
320. Generalized Abbreviation
Description: A word’s generalized abbreviation can be constructed by replacing any number of non-adjacent substrings with their lengths. Return a list of all possible generalized abbreviations of word.
Java Solution:
public List<String> generateAbbreviations(String word) {
List<String> result = new ArrayList<>();
backtrack(word, 0, "", 0, result);
return result;
}
private void backtrack(String word, int pos, String current, int count, List<String> result) {
if (pos == word.length()) {
if (count > 0) {
current += count;
}
result.add(current);
return;
}
// Abbreviate current character
backtrack(word, pos + 1, current, count + 1, result);
// Keep current character
backtrack(word, pos + 1, current + (count > 0 ? count : "") + word.charAt(pos), 0, result);
}
Explanation: Use backtracking to decide for each character whether to abbreviate it or keep it. Track count of consecutive abbreviated characters.
- Time Complexity: O(2^n)
- Space Complexity: O(n)
321. Create Maximum Number
Description: You are given two integer arrays nums1 and nums2 of lengths m and n. Create the maximum number of length k <= m + n from digits of the two arrays. The relative order of digits from the same array must be preserved.
Java Solution:
public int[] maxNumber(int[] nums1, int[] nums2, int k) {
int m = nums1.length;
int n = nums2.length;
int[] result = new int[k];
for (int i = Math.max(0, k - n); i <= Math.min(k, m); i++) {
int[] candidate = merge(maxArray(nums1, i), maxArray(nums2, k - i), k);
if (greater(candidate, 0, result, 0)) {
result = candidate;
}
}
return result;
}
private int[] maxArray(int[] nums, int k) {
int n = nums.length;
int[] result = new int[k];
int j = 0;
for (int i = 0; i < n; i++) {
while (n - i > k - j && j > 0 && result[j - 1] < nums[i]) {
j--;
}
if (j < k) {
result[j++] = nums[i];
}
}
return result;
}
private int[] merge(int[] nums1, int[] nums2, int k) {
int[] result = new int[k];
int i = 0, j = 0;
for (int r = 0; r < k; r++) {
result[r] = greater(nums1, i, nums2, j) ? nums1[i++] : nums2[j++];
}
return result;
}
private boolean greater(int[] nums1, int i, int[] nums2, int j) {
while (i < nums1.length && j < nums2.length && nums1[i] == nums2[j]) {
i++;
j++;
}
return j == nums2.length || (i < nums1.length && nums1[i] > nums2[j]);
}
Explanation: For each valid split, find max subsequence from each array, merge them, and track overall maximum.
- Time Complexity: O(k * (m + n)²)
- Space Complexity: O(k)
322. Coin Change
Description: You are given an integer array coins representing coins of different denominations and an integer amount. Return the fewest number of coins needed to make up that amount.
Java Solution:
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount + 1];
Arrays.fill(dp, amount + 1);
dp[0] = 0;
for (int i = 1; i <= amount; i++) {
for (int coin : coins) {
if (coin <= i) {
dp[i] = Math.min(dp[i], dp[i - coin] + 1);
}
}
}
return dp[amount] > amount ? -1 : dp[amount];
}
Explanation: Dynamic programming where dp[i] is minimum coins for amount i. For each amount, try all coins and take minimum.
- Time Complexity: O(amount * n)
- Space Complexity: O(amount)
323. Number of Connected Components in an Undirected Graph
Description: You have a graph of n nodes. You are given an integer n and an array edges. Return the number of connected components in the graph.
Java Solution:
public int countComponents(int n, int[][] edges) {
int[] parent = new int[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
}
for (int[] edge : edges) {
int root1 = find(parent, edge[0]);
int root2 = find(parent, edge[1]);
if (root1 != root2) {
parent[root1] = root2;
n--;
}
}
return n;
}
private int find(int[] parent, int x) {
if (parent[x] != x) {
parent[x] = find(parent, parent[x]);
}
return parent[x];
}
Explanation: Use Union-Find to connect nodes. Each union reduces component count by 1. Final count is number of components.
- Time Complexity: O(E * α(n))
- Space Complexity: O(n)
324. Wiggle Sort II
Description: Given an integer array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]…
Java Solution:
public void wiggleSort(int[] nums) {
int n = nums.length;
int[] copy = Arrays.copyOf(nums, n);
Arrays.sort(copy);
int mid = (n - 1) / 2;
int end = n - 1;
for (int i = 0; i < n; i++) {
if (i % 2 == 0) {
nums[i] = copy[mid--];
} else {
nums[i] = copy[end--];
}
}
}
Explanation: Sort array, then place median and smaller values at even indices, larger values at odd indices, working backwards to avoid adjacent duplicates.
- Time Complexity: O(n log n)
- Space Complexity: O(n)
325. Maximum Size Subarray Sum Equals k
Description: Given an integer array nums and an integer k, return the maximum length of a subarray that sums to k. If there is not one, return 0 instead.
Java Solution:
public int maxSubArrayLen(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
int maxLen = 0;
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
if (map.containsKey(sum - k)) {
maxLen = Math.max(maxLen, i - map.get(sum - k));
}
if (!map.containsKey(sum)) {
map.put(sum, i);
}
}
return maxLen;
}
Explanation: Use hash map to store first occurrence of each prefix sum. If sum - k exists, we found a subarray summing to k.
- Time Complexity: O(n)
- Space Complexity: O(n)
326. Power of Three
Description: Given an integer n, return true if it is a power of three. Otherwise, return false.
Java Solution:
public boolean isPowerOfThree(int n) {
if (n <= 0) {
return false;
}
while (n % 3 == 0) {
n /= 3;
}
return n == 1;
}
Explanation: Repeatedly divide by 3. If we end up with 1, n was a power of 3.
- Time Complexity: O(log n)
- Space Complexity: O(1)
327. Count of Range Sum
Description: Given an integer array nums and two integers lower and upper, return the number of range sums that lie in [lower, upper] inclusive.
Java Solution:
public int countRangeSum(int[] nums, int lower, int upper) {
int n = nums.length;
long[] prefixSum = new long[n + 1];
for (int i = 0; i < n; i++) {
prefixSum[i + 1] = prefixSum[i] + nums[i];
}
return countWhileMergeSort(prefixSum, 0, n + 1, lower, upper);
}
private int countWhileMergeSort(long[] sums, int start, int end, int lower, int upper) {
if (end - start <= 1) {
return 0;
}
int mid = (start + end) / 2;
int count = countWhileMergeSort(sums, start, mid, lower, upper)
+ countWhileMergeSort(sums, mid, end, lower, upper);
int j = mid, k = mid, t = mid;
long[] cache = new long[end - start];
int r = 0;
for (int i = start; i < mid; i++) {
while (k < end && sums[k] - sums[i] < lower) k++;
while (j < end && sums[j] - sums[i] <= upper) j++;
count += j - k;
while (t < end && sums[t] < sums[i]) cache[r++] = sums[t++];
cache[r++] = sums[i];
}
System.arraycopy(cache, 0, sums, start, r);
return count;
}
Explanation: Use merge sort with prefix sums. During merge, count pairs where difference is in [lower, upper].
- Time Complexity: O(n log n)
- Space Complexity: O(n)
328. Odd Even Linked List
Description: Given the head of a singly linked list, group all nodes with odd indices together followed by nodes with even indices, and return the reordered list.
Java Solution:
public ListNode oddEvenList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode odd = head;
ListNode even = head.next;
ListNode evenHead = even;
while (even != null && even.next != null) {
odd.next = even.next;
odd = odd.next;
even.next = odd.next;
even = even.next;
}
odd.next = evenHead;
return head;
}
Explanation: Maintain two lists: odd-indexed nodes and even-indexed nodes. Link them together at the end.
- Time Complexity: O(n)
- Space Complexity: O(1)
329. Longest Increasing Path in a Matrix
Description: Given an m x n integers matrix, return the length of the longest increasing path in matrix.
Java Solution:
public int longestIncreasingPath(int[][] matrix) {
if (matrix == null || matrix.length == 0) {
return 0;
}
int m = matrix.length;
int n = matrix[0].length;
int[][] memo = new int[m][n];
int maxPath = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
maxPath = Math.max(maxPath, dfs(matrix, i, j, memo));
}
}
return maxPath;
}
private int dfs(int[][] matrix, int i, int j, int[][] memo) {
if (memo[i][j] != 0) {
return memo[i][j];
}
int m = matrix.length;
int n = matrix[0].length;
int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int maxLen = 1;
for (int[] dir : dirs) {
int newI = i + dir[0];
int newJ = j + dir[1];
if (newI >= 0 && newI < m && newJ >= 0 && newJ < n &&
matrix[newI][newJ] > matrix[i][j]) {
maxLen = Math.max(maxLen, 1 + dfs(matrix, newI, newJ, memo));
}
}
memo[i][j] = maxLen;
return maxLen;
}
Explanation: DFS with memoization from each cell. Only move to cells with larger values. Cache results to avoid recomputation.
- Time Complexity: O(m * n)
- Space Complexity: O(m * n)
330. Patching Array
Description: Given a sorted integer array nums and an integer n, add/patch elements to the array such that any number in the range [1, n] can be formed by the sum of some elements in the array. Return the minimum number of patches required.
Java Solution:
public int minPatches(int[] nums, int n) {
long miss = 1;
int patches = 0;
int i = 0;
while (miss <= n) {
if (i < nums.length && nums[i] <= miss) {
miss += nums[i];
i++;
} else {
miss += miss;
patches++;
}
}
return patches;
}
Explanation: Track smallest missing sum. If current number <= missing, add it. Otherwise, patch with missing value itself to double coverage.
- Time Complexity: O(m + log n) where m is array length
- Space Complexity: O(1)
331. Verify Preorder Serialization of a Binary Tree
Description: One way to serialize a binary tree is to use preorder traversal. Given a string of comma-separated values preorder, return true if it is a correct preorder traversal serialization of a binary tree.
Java Solution:
public boolean isValidSerialization(String preorder) {
String[] nodes = preorder.split(",");
int slots = 1;
for (String node : nodes) {
slots--;
if (slots < 0) {
return false;
}
if (!node.equals("#")) {
slots += 2;
}
}
return slots == 0;
}
Explanation: Track available slots. Each node consumes 1 slot. Non-null nodes add 2 slots (for children). Valid if all slots used.
- Time Complexity: O(n)
- Space Complexity: O(n)
332. Reconstruct Itinerary
Description: You are given a list of airline tickets where tickets[i] = [from, to] represent the departure and arrival airports. Reconstruct the itinerary in order and return it starting from JFK.
Java Solution:
public List<String> findItinerary(List<List<String>> tickets) {
Map<String, PriorityQueue<String>> graph = new HashMap<>();
for (List<String> ticket : tickets) {
graph.putIfAbsent(ticket.get(0), new PriorityQueue<>());
graph.get(ticket.get(0)).offer(ticket.get(1));
}
LinkedList<String> result = new LinkedList<>();
dfs("JFK", graph, result);
return result;
}
private void dfs(String airport, Map<String, PriorityQueue<String>> graph, LinkedList<String> result) {
PriorityQueue<String> arrivals = graph.get(airport);
while (arrivals != null && !arrivals.isEmpty()) {
dfs(arrivals.poll(), graph, result);
}
result.addFirst(airport);
}
Explanation: Build graph with priority queues for lexical order. Use Hierholzer’s algorithm to find Eulerian path, adding airports in reverse.
- Time Complexity: O(E log E)
- Space Complexity: O(E)
333. Largest BST Subtree
Description: Given the root of a binary tree, find the largest subtree which is also a Binary Search Tree (BST).
Java Solution:
public int largestBSTSubtree(TreeNode root) {
return dfs(root)[0];
}
private int[] dfs(TreeNode node) {
if (node == null) {
return new int[]{0, Integer.MAX_VALUE, Integer.MIN_VALUE};
}
int[] left = dfs(node.left);
int[] right = dfs(node.right);
if (left[0] == -1 || right[0] == -1 || node.val <= left[2] || node.val >= right[1]) {
return new int[]{-1, 0, 0};
}
int size = left[0] + right[0] + 1;
int min = left[1] == Integer.MAX_VALUE ? node.val : left[1];
int max = right[2] == Integer.MIN_VALUE ? node.val : right[2];
return new int[]{size, min, max};
}
Explanation: Post-order DFS returning [size, min, max]. Check if current subtree is BST based on children’s bounds.
- Time Complexity: O(n)
- Space Complexity: O(h)
334. Increasing Triplet Subsequence
Description: Given an integer array nums, return true if there exists a triple of indices (i, j, k) such that i < j < k and nums[i] < nums[j] < nums[k].
Java Solution:
public boolean increasingTriplet(int[] nums) {
int first = Integer.MAX_VALUE;
int second = Integer.MAX_VALUE;
for (int num : nums) {
if (num <= first) {
first = num;
} else if (num <= second) {
second = num;
} else {
return true;
}
}
return false;
}
Explanation: Track two smallest values seen so far. If we find a value larger than both, we have an increasing triplet.
- Time Complexity: O(n)
- Space Complexity: O(1)
335. Self Crossing
Description: You are given an array of integers distance. You start at point (0,0) on an X-Y plane and move distance[0] north, then distance[1] west, distance[2] south, and so on. Return true if your path crosses itself.
Java Solution:
public boolean isSelfCrossing(int[] distance) {
int n = distance.length;
for (int i = 3; i < n; i++) {
// Fourth line crosses first line
if (i >= 3 && distance[i] >= distance[i - 2] && distance[i - 1] <= distance[i - 3]) {
return true;
}
// Fifth line crosses second line
if (i >= 4 && distance[i - 1] == distance[i - 3] &&
distance[i] + distance[i - 4] >= distance[i - 2]) {
return true;
}
// Sixth line crosses third line
if (i >= 5 && distance[i - 2] >= distance[i - 4] &&
distance[i - 3] >= distance[i - 1] &&
distance[i - 1] + distance[i - 5] >= distance[i - 3] &&
distance[i] + distance[i - 4] >= distance[i - 2]) {
return true;
}
}
return false;
}
Explanation: Check three crossing patterns: 4th line crosses 1st, 5th crosses 2nd, or 6th crosses 3rd.
- Time Complexity: O(n)
- Space Complexity: O(1)
336. Palindrome Pairs
Description: Given a list of unique words, return all pairs of distinct indices (i, j) such that the concatenation of words[i] + words[j] is a palindrome.
Java Solution:
public List<List<Integer>> palindromePairs(String[] words) {
List<List<Integer>> result = new ArrayList<>();
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < words.length; i++) {
map.put(words[i], i);
}
for (int i = 0; i < words.length; i++) {
String word = words[i];
for (int j = 0; j <= word.length(); j++) {
String left = word.substring(0, j);
String right = word.substring(j);
if (isPalindrome(left)) {
String reversedRight = new StringBuilder(right).reverse().toString();
if (map.containsKey(reversedRight) && map.get(reversedRight) != i) {
result.add(Arrays.asList(map.get(reversedRight), i));
}
}
if (j != word.length() && isPalindrome(right)) {
String reversedLeft = new StringBuilder(left).reverse().toString();
if (map.containsKey(reversedLeft) && map.get(reversedLeft) != i) {
result.add(Arrays.asList(i, map.get(reversedLeft)));
}
}
}
}
return result;
}
private boolean isPalindrome(String s) {
int left = 0, right = s.length() - 1;
while (left < right) {
if (s.charAt(left++) != s.charAt(right--)) {
return false;
}
}
return true;
}
Explanation: For each word, try all split points. If one part is palindrome, check if reverse of other part exists in map.
- Time Complexity: O(n * k²) where k is average word length
- Space Complexity: O(n * k)
337. House Robber III
Description: The thief has found himself a new place for his thievery again. This time, all houses are arranged in a binary tree. Two directly-linked houses have security systems connected. Determine the maximum amount of money the thief can rob.
Java Solution:
public int rob(TreeNode root) {
int[] result = robHelper(root);
return Math.max(result[0], result[1]);
}
private int[] robHelper(TreeNode node) {
if (node == null) {
return new int[]{0, 0};
}
int[] left = robHelper(node.left);
int[] right = robHelper(node.right);
int rob = node.val + left[1] + right[1];
int notRob = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
return new int[]{rob, notRob};
}
Explanation: For each node, return [rob_current, skip_current]. If rob current, add children’s skip values. Otherwise, take max of children’s values.
- Time Complexity: O(n)
- Space Complexity: O(h)
338. Counting Bits
Description: Given an integer n, return an array ans of length n + 1 such that for each i (0 <= i <= n), ans[i] is the number of 1’s in the binary representation of i.
Java Solution:
public int[] countBits(int n) {
int[] result = new int[n + 1];
for (int i = 1; i <= n; i++) {
result[i] = result[i >> 1] + (i & 1);
}
return result;
}
Explanation: Number of 1s in i equals number in i/2 plus 1 if i is odd. Use right shift and check last bit.
- Time Complexity: O(n)
- Space Complexity: O(1)
339. Nested List Weight Sum
Description: You are given a nested list of integers nestedList. Each element is either an integer or a list whose elements may also be integers or other lists. Return the sum of all integers in nestedList weighted by their depth.
Java Solution:
public int depthSum(List<NestedInteger> nestedList) {
return dfs(nestedList, 1);
}
private int dfs(List<NestedInteger> list, int depth) {
int sum = 0;
for (NestedInteger ni : list) {
if (ni.isInteger()) {
sum += ni.getInteger() * depth;
} else {
sum += dfs(ni.getList(), depth + 1);
}
}
return sum;
}
Explanation: DFS through nested structure, multiplying each integer by its depth and summing.
- Time Complexity: O(n)
- Space Complexity: O(d) where d is max depth
340. Longest Substring with At Most K Distinct Characters
Description: Given a string s and an integer k, return the length of the longest substring of s that contains at most k distinct characters.
Java Solution:
public int lengthOfLongestSubstringKDistinct(String s, int k) {
if (k == 0) {
return 0;
}
Map<Character, Integer> map = new HashMap<>();
int maxLen = 0;
int left = 0;
for (int right = 0; right < s.length(); right++) {
char c = s.charAt(right);
map.put(c, map.getOrDefault(c, 0) + 1);
while (map.size() > k) {
char leftChar = s.charAt(left);
map.put(leftChar, map.get(leftChar) - 1);
if (map.get(leftChar) == 0) {
map.remove(leftChar);
}
left++;
}
maxLen = Math.max(maxLen, right - left + 1);
}
return maxLen;
}
Explanation: Sliding window with hash map tracking character frequencies. Shrink window when distinct characters exceed k.
- Time Complexity: O(n)
- Space Complexity: O(k)
341. Flatten Nested List Iterator
Description: You are given a nested list of integers nestedList. Implement an iterator to flatten it.
Java Solution:
public class NestedIterator implements Iterator<Integer> {
private Stack<NestedInteger> stack;
public NestedIterator(List<NestedInteger> nestedList) {
stack = new Stack<>();
for (int i = nestedList.size() - 1; i >= 0; i--) {
stack.push(nestedList.get(i));
}
}
@Override
public Integer next() {
return stack.pop().getInteger();
}
@Override
public boolean hasNext() {
while (!stack.isEmpty()) {
NestedInteger curr = stack.peek();
if (curr.isInteger()) {
return true;
}
stack.pop();
for (int i = curr.getList().size() - 1; i >= 0; i--) {
stack.push(curr.getList().get(i));
}
}
return false;
}
}
Explanation: Use stack to store nested integers in reverse order. In hasNext, expand lists until finding an integer or exhausting stack.
- Time Complexity: O(1) amortized
- Space Complexity: O(d) where d is max depth
342. Power of Four
Description: Given an integer n, return true if it is a power of four. Otherwise, return false.
Java Solution:
public boolean isPowerOfFour(int n) {
return n > 0 && (n & (n - 1)) == 0 && (n & 0x55555555) != 0;
}
Explanation: Check: n is positive, n is power of 2 (n & (n-1) == 0), and 1 bit is at odd position (check with 0x55555555 mask).
- Time Complexity: O(1)
- Space Complexity: O(1)
343. Integer Break
Description: Given an integer n, break it into the sum of k positive integers where k >= 2, and maximize the product of those integers. Return the maximum product you can get.
Java Solution:
public int integerBreak(int n) {
if (n == 2) {
return 1;
}
if (n == 3) {
return 2;
}
int product = 1;
while (n > 4) {
product *= 3;
n -= 3;
}
return product * n;
}
Explanation: Greedy approach: maximize number of 3s. If remainder is 1, replace one 3 with two 2s. Otherwise multiply by remainder.
- Time Complexity: O(n)
- Space Complexity: O(1)
344. Reverse String
Description: Write a function that reverses a string. The input string is given as an array of characters s.
Java Solution:
public void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
while (left < right) {
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
Explanation: Two pointers approach: swap characters from both ends moving toward center.
- Time Complexity: O(n)
- Space Complexity: O(1)
345. Reverse Vowels of a String
Description: Given a string s, reverse only all the vowels in the string and return it.
Java Solution:
public String reverseVowels(String s) {
char[] chars = s.toCharArray();
Set<Character> vowels = new HashSet<>(Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'));
int left = 0;
int right = chars.length - 1;
while (left < right) {
while (left < right && !vowels.contains(chars[left])) {
left++;
}
while (left < right && !vowels.contains(chars[right])) {
right--;
}
if (left < right) {
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
}
return new String(chars);
}
Explanation: Two pointers: find vowels from both ends and swap them. Skip non-vowels.
- Time Complexity: O(n)
- Space Complexity: O(n)
346. Moving Average from Data Stream
Description: Given a stream of integers and a window size, calculate the moving average of all integers in the sliding window.
Java Solution:
class MovingAverage {
private Queue<Integer> queue;
private int size;
private double sum;
public MovingAverage(int size) {
this.queue = new LinkedList<>();
this.size = size;
this.sum = 0;
}
public double next(int val) {
if (queue.size() == size) {
sum -= queue.poll();
}
queue.offer(val);
sum += val;
return sum / queue.size();
}
}
Explanation: Use queue to maintain window. Track sum to calculate average efficiently. Remove oldest when full.
- Time Complexity: O(1)
- Space Complexity: O(size)
347. Top K Frequent Elements
Description: Given an integer array nums and an integer k, return the k most frequent elements.
Java Solution:
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> freq = new HashMap<>();
for (int num : nums) {
freq.put(num, freq.getOrDefault(num, 0) + 1);
}
PriorityQueue<Integer> heap = new PriorityQueue<>((a, b) -> freq.get(a) - freq.get(b));
for (int num : freq.keySet()) {
heap.offer(num);
if (heap.size() > k) {
heap.poll();
}
}
int[] result = new int[k];
for (int i = 0; i < k; i++) {
result[i] = heap.poll();
}
return result;
}
Explanation: Count frequencies with hash map. Use min heap of size k to keep top k frequent elements.
- Time Complexity: O(n log k)
- Space Complexity: O(n)
348. Design Tic-Tac-Toe
Description: Design a Tic-tac-toe game that is played between two players on an n x n grid. Assume both players play optimally.
Java Solution:
class TicTacToe {
private int[] rows;
private int[] cols;
private int diagonal;
private int antiDiagonal;
private int n;
public TicTacToe(int n) {
this.n = n;
rows = new int[n];
cols = new int[n];
diagonal = 0;
antiDiagonal = 0;
}
public int move(int row, int col, int player) {
int toAdd = player == 1 ? 1 : -1;
rows[row] += toAdd;
cols[col] += toAdd;
if (row == col) {
diagonal += toAdd;
}
if (row + col == n - 1) {
antiDiagonal += toAdd;
}
if (Math.abs(rows[row]) == n || Math.abs(cols[col]) == n ||
Math.abs(diagonal) == n || Math.abs(antiDiagonal) == n) {
return player;
}
return 0;
}
}
Explanation: Track sums for each row, column, and diagonal. Player 1 adds 1, player 2 adds -1. Win when absolute value reaches n.
- Time Complexity: O(1) per move
- Space Complexity: O(n)
349. Intersection of Two Arrays
Description: Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the result must be unique.
Java Solution:
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> set1 = new HashSet<>();
Set<Integer> resultSet = new HashSet<>();
for (int num : nums1) {
set1.add(num);
}
for (int num : nums2) {
if (set1.contains(num)) {
resultSet.add(num);
}
}
int[] result = new int[resultSet.size()];
int i = 0;
for (int num : resultSet) {
result[i++] = num;
}
return result;
}
Explanation: Use hash sets to find common elements. First set stores nums1, check nums2 against it.
- Time Complexity: O(m + n)
- Space Complexity: O(m + n)
350. Intersection of Two Arrays II
Description: Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the result should appear as many times as it shows in both arrays.
Java Solution:
public int[] intersect(int[] nums1, int[] nums2) {
Map<Integer, Integer> map = new HashMap<>();
List<Integer> result = new ArrayList<>();
for (int num : nums1) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
for (int num : nums2) {
if (map.containsKey(num) && map.get(num) > 0) {
result.add(num);
map.put(num, map.get(num) - 1);
}
}
int[] answer = new int[result.size()];
for (int i = 0; i < result.size(); i++) {
answer[i] = result.get(i);
}
return answer;
}
Explanation: Count frequencies of nums1 in hash map. For each num in nums2, if count > 0, add to result and decrement count.
- Time Complexity: O(m + n)
- Space Complexity: O(min(m, n))
351. Android Unlock Patterns
Description: Given an Android 3x3 key lock screen and two integers m and n, where 1 ≤ m ≤ n ≤ 9, count the total number of unlock patterns of the Android lock screen, which consist of minimum of m keys and maximum n keys.
Java Solution:
public int numberOfPatterns(int m, int n) {
int[][] skip = new int[10][10];
skip[1][3] = skip[3][1] = 2;
skip[1][7] = skip[7][1] = 4;
skip[3][9] = skip[9][3] = 6;
skip[7][9] = skip[9][7] = 8;
skip[1][9] = skip[9][1] = skip[2][8] = skip[8][2] = skip[3][7] = skip[7][3] = skip[4][6] = skip[6][4] = 5;
boolean[] visited = new boolean[10];
int count = 0;
for (int i = m; i <= n; i++) {
count += dfs(skip, visited, 1, i - 1) * 4;
count += dfs(skip, visited, 2, i - 1) * 4;
count += dfs(skip, visited, 5, i - 1);
}
return count;
}
private int dfs(int[][] skip, boolean[] visited, int cur, int remain) {
if (remain < 0) return 0;
if (remain == 0) return 1;
visited[cur] = true;
int count = 0;
for (int i = 1; i <= 9; i++) {
if (!visited[i] && (skip[cur][i] == 0 || visited[skip[cur][i]])) {
count += dfs(skip, visited, i, remain - 1);
}
}
visited[cur] = false;
return count;
}
Explanation: Uses DFS with backtracking to count valid patterns. Exploits keypad symmetry for optimization.
- Time Complexity: O(n!)
- Space Complexity: O(1)
352. Data Stream as Disjoint Intervals
Description: Given a data stream input of non-negative integers, summarize the numbers seen so far as a list of disjoint intervals.
Java Solution:
class SummaryRanges {
TreeMap<Integer, Integer> intervals;
public SummaryRanges() {
intervals = new TreeMap<>();
}
public void addNum(int val) {
if (intervals.containsKey(val)) return;
Integer low = intervals.lowerKey(val);
Integer high = intervals.higherKey(val);
if (low != null && high != null && intervals.get(low) + 1 == val && val + 1 == high) {
intervals.put(low, intervals.get(high));
intervals.remove(high);
} else if (low != null && intervals.get(low) + 1 >= val) {
intervals.put(low, Math.max(intervals.get(low), val));
} else if (high != null && val + 1 == high) {
intervals.put(val, intervals.get(high));
intervals.remove(high);
} else {
intervals.put(val, val);
}
}
public int[][] getIntervals() {
int[][] result = new int[intervals.size()][2];
int i = 0;
for (Map.Entry<Integer, Integer> entry : intervals.entrySet()) {
result[i][0] = entry.getKey();
result[i][1] = entry.getValue();
i++;
}
return result;
}
}
Explanation: Uses TreeMap to maintain sorted intervals with efficient merge operations.
- Time Complexity: O(log n) for addNum, O(n) for getIntervals
- Space Complexity: O(n)
353. Design Snake Game
Description: Design a Snake game that is played on a device with screen size height x width. The snake is initially positioned at the top left corner (0,0) with length 1.
Java Solution:
class SnakeGame {
Set<Integer> body;
Deque<Integer> snakeBody;
int[][] food;
int foodIndex, width, height;
public SnakeGame(int width, int height, int[][] food) {
this.width = width;
this.height = height;
this.food = food;
this.body = new HashSet<>();
this.snakeBody = new LinkedList<>();
this.foodIndex = 0;
body.add(0);
snakeBody.offerLast(0);
}
public int move(String direction) {
int head = snakeBody.peekFirst();
int r = head / width, c = head % width;
if (direction.equals("U")) r--;
else if (direction.equals("D")) r++;
else if (direction.equals("L")) c--;
else if (direction.equals("R")) c++;
int newHead = r * width + c;
if (r < 0 || r >= height || c < 0 || c >= width) return -1;
if (foodIndex < food.length && r == food[foodIndex][0] && c == food[foodIndex][1]) {
foodIndex++;
snakeBody.offerFirst(newHead);
body.add(newHead);
return foodIndex;
}
int tail = snakeBody.pollLast();
body.remove(tail);
if (body.contains(newHead)) return -1;
snakeBody.offerFirst(newHead);
body.add(newHead);
return foodIndex;
}
}
Explanation: Uses deque for snake body and set for O(1) collision detection.
- Time Complexity: O(1) per move
- Space Complexity: O(n)
354. Russian Doll Envelopes
Description: Return the maximum number of envelopes you can Russian doll (i.e., put one inside the other).
Java Solution:
public int maxEnvelopes(int[][] envelopes) {
Arrays.sort(envelopes, (a, b) -> {
if (a[0] != b[0]) return a[0] - b[0];
return b[1] - a[1];
});
int[] dp = new int[envelopes.length];
int len = 0;
for (int[] envelope : envelopes) {
int index = Arrays.binarySearch(dp, 0, len, envelope[1]);
if (index < 0) index = -(index + 1);
dp[index] = envelope[1];
if (index == len) len++;
}
return len;
}
Explanation: Sort by width ascending and height descending, then find LIS of heights.
- Time Complexity: O(n log n)
- Space Complexity: O(n)
355. Design Twitter
Description: Design a simplified version of Twitter with post, follow/unfollow, and news feed features.
Java Solution:
class Twitter {
private int timestamp = 0;
private Map<Integer, User> userMap = new HashMap<>();
class Tweet {
int id, time;
Tweet next;
Tweet(int id) {
this.id = id;
this.time = timestamp++;
}
}
class User {
int id;
Set<Integer> followed = new HashSet<>();
Tweet tweetHead;
User(int id) {
this.id = id;
follow(id);
}
void follow(int id) {
followed.add(id);
}
void unfollow(int id) {
followed.remove(id);
}
void post(int tweetId) {
Tweet t = new Tweet(tweetId);
t.next = tweetHead;
tweetHead = t;
}
}
public void postTweet(int userId, int tweetId) {
if (!userMap.containsKey(userId)) userMap.put(userId, new User(userId));
userMap.get(userId).post(tweetId);
}
public List<Integer> getNewsFeed(int userId) {
List<Integer> result = new ArrayList<>();
if (!userMap.containsKey(userId)) return result;
PriorityQueue<Tweet> pq = new PriorityQueue<>((a, b) -> b.time - a.time);
for (int user : userMap.get(userId).followed) {
Tweet t = userMap.get(user).tweetHead;
if (t != null) pq.offer(t);
}
int count = 0;
while (!pq.isEmpty() && count < 10) {
Tweet t = pq.poll();
result.add(t.id);
count++;
if (t.next != null) pq.offer(t.next);
}
return result;
}
public void follow(int followerId, int followeeId) {
if (!userMap.containsKey(followerId)) userMap.put(followerId, new User(followerId));
if (!userMap.containsKey(followeeId)) userMap.put(followeeId, new User(followeeId));
userMap.get(followerId).follow(followeeId);
}
public void unfollow(int followerId, int followeeId) {
if (!userMap.containsKey(followerId) || followerId == followeeId) return;
userMap.get(followerId).unfollow(followeeId);
}
}
Explanation: Uses linked lists for tweets and priority queue for merging news feeds.
- Time Complexity: O(n log k) for getNewsFeed
- Space Complexity: O(u + t)
356. Line Reflection
Description: Find if there is such a line parallel to the y-axis that reflects the given points symmetrically.
Java Solution:
public boolean isReflected(int[][] points) {
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
Set<String> set = new HashSet<>();
for (int[] point : points) {
min = Math.min(min, point[0]);
max = Math.max(max, point[0]);
set.add(point[0] + "," + point[1]);
}
int sum = min + max;
for (int[] point : points) {
if (!set.contains((sum - point[0]) + "," + point[1])) return false;
}
return true;
}
Explanation: Finds reflection line at x = (min + max) / 2 and verifies all points have reflections.
- Time Complexity: O(n)
- Space Complexity: O(n)
357. Count Numbers with Unique Digits
Description: Given an integer n, return the count of all numbers with unique digits, x, where 0 <= x < 10^n.
Java Solution:
public int countNumbersWithUniqueDigits(int n) {
if (n == 0) return 1;
int result = 10, uniqueDigits = 9, availableNumbers = 9;
while (n-- > 1 && availableNumbers > 0) {
uniqueDigits *= availableNumbers;
result += uniqueDigits;
availableNumbers--;
}
return result;
}
Explanation: Uses combinatorics: n-digit numbers with unique digits = 9 * 9 * 8 * … * (11-n).
- Time Complexity: O(n)
- Space Complexity: O(1)
358. Rearrange String k Distance Apart
Description: Rearrange string s such that the same characters are at least distance k from each other.
Java Solution:
public String rearrangeString(String s, int k) {
if (k == 0) return s;
int[] count = new int[26];
for (char c : s.toCharArray()) count[c - 'a']++;
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> b[1] - a[1]);
for (int i = 0; i < 26; i++) {
if (count[i] > 0) pq.offer(new int[]{i, count[i]});
}
StringBuilder result = new StringBuilder();
Queue<int[]> waitQueue = new LinkedList<>();
while (!pq.isEmpty()) {
int[] cur = pq.poll();
result.append((char)(cur[0] + 'a'));
cur[1]--;
waitQueue.offer(cur);
if (waitQueue.size() < k) continue;
int[] front = waitQueue.poll();
if (front[1] > 0) pq.offer(front);
}
return result.length() == s.length() ? result.toString() : "";
}
Explanation: Uses max heap and wait queue to ensure k distance between same characters.
- Time Complexity: O(n)
- Space Complexity: O(1)
359. Logger Rate Limiter
Description: Design a logger that prints messages at most every 10 seconds.
Java Solution:
class Logger {
Map<String, Integer> messageMap = new HashMap<>();
public boolean shouldPrintMessage(int timestamp, String message) {
if (!messageMap.containsKey(message) || timestamp - messageMap.get(message) >= 10) {
messageMap.put(message, timestamp);
return true;
}
return false;
}
}
Explanation: Uses hash map to track last timestamp for each message.
- Time Complexity: O(1)
- Space Complexity: O(n)
360. Sort Transformed Array
Description: Apply quadratic function f(x) = ax² + bx + c to sorted array and return sorted result.
Java Solution:
public int[] sortTransformedArray(int[] nums, int a, int b, int c) {
int n = nums.length, i = 0, j = n - 1;
int[] result = new int[n];
int index = a >= 0 ? n - 1 : 0;
while (i <= j) {
int left = a * nums[i] * nums[i] + b * nums[i] + c;
int right = a * nums[j] * nums[j] + b * nums[j] + c;
if (a >= 0) {
if (left >= right) {
result[index--] = left;
i++;
} else {
result[index--] = right;
j--;
}
} else {
if (left <= right) {
result[index++] = left;
i++;
} else {
result[index++] = right;
j--;
}
}
}
return result;
}
Explanation: Uses two pointers to fill result from appropriate end based on parabola direction.
- Time Complexity: O(n)
- Space Complexity: O(1)
361. Bomb Enemy
Description: Given a 2D grid, each cell is either a wall ‘W’, an enemy ‘E’ or empty ‘0’. Return the maximum enemies you can kill using one bomb. The bomb kills all the enemies in the same row and column from the planted point until it hits a wall since the wall is too strong to be destroyed.
Java Solution:
public int maxKilledEnemies(char[][] grid) {
if (grid == null || grid.length == 0) return 0;
int m = grid.length, n = grid[0].length, result = 0, rowHits = 0;
int[] colHits = new int[n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (j == 0 || grid[i][j-1] == 'W') {
rowHits = 0;
for (int k = j; k < n && grid[i][k] != 'W'; k++)
rowHits += grid[i][k] == 'E' ? 1 : 0;
}
if (i == 0 || grid[i-1][j] == 'W') {
colHits[j] = 0;
for (int k = i; k < m && grid[k][j] != 'W'; k++)
colHits[j] += grid[k][j] == 'E' ? 1 : 0;
}
if (grid[i][j] == '0')
result = Math.max(result, rowHits + colHits[j]);
}
}
return result;
}
Explanation: Caches row and column enemy counts, recomputing only when hitting walls for efficiency.
- Time Complexity: O(mn)
- Space Complexity: O(n)
362. Design Hit Counter
Description: Design a hit counter which counts the number of hits received in the past 5 minutes (300 seconds).
Java Solution:
class HitCounter {
Queue<Integer> queue;
public HitCounter() {
queue = new LinkedList<>();
}
public void hit(int timestamp) {
queue.offer(timestamp);
}
public int getHits(int timestamp) {
while (!queue.isEmpty() && timestamp - queue.peek() >= 300) {
queue.poll();
}
return queue.size();
}
}
Explanation: Uses a queue to store timestamps and removes entries older than 300 seconds on each getHits call.
- Time Complexity: O(1) for hit, O(n) for getHits
- Space Complexity: O(n)
363. Max Sum of Rectangle No Larger Than K
Description: Given an m x n matrix and an integer k, return the max sum of a rectangle in the matrix such that its sum is no larger than k.
Java Solution:
public int maxSumSubmatrix(int[][] matrix, int k) {
int m = matrix.length, n = matrix[0].length;
int result = Integer.MIN_VALUE;
for (int left = 0; left < n; left++) {
int[] sums = new int[m];
for (int right = left; right < n; right++) {
for (int i = 0; i < m; i++) {
sums[i] += matrix[i][right];
}
TreeSet<Integer> set = new TreeSet<>();
set.add(0);
int curSum = 0;
for (int sum : sums) {
curSum += sum;
Integer ceiling = set.ceiling(curSum - k);
if (ceiling != null) {
result = Math.max(result, curSum - ceiling);
}
set.add(curSum);
}
}
}
return result;
}
Explanation: Fixes left and right columns, uses TreeSet to find maximum subarray sum no larger than k.
- Time Complexity: O(n²m log m)
- Space Complexity: O(m)
364. Nested List Weight Sum II
Description: Given a nested list of integers, return the sum of all integers in the list weighted by their depth. Each element is either an integer or a list whose elements may also be integers or other lists. The weight of an integer is the number of lists that it is inside of, but in this problem, depth is counted from bottom up.
Java Solution:
public int depthSumInverse(List<NestedInteger> nestedList) {
int unweighted = 0, weighted = 0;
while (!nestedList.isEmpty()) {
List<NestedInteger> nextLevel = new ArrayList<>();
for (NestedInteger ni : nestedList) {
if (ni.isInteger()) {
unweighted += ni.getInteger();
} else {
nextLevel.addAll(ni.getList());
}
}
weighted += unweighted;
nestedList = nextLevel;
}
return weighted;
}
Explanation: Uses BFS approach, accumulating unweighted sum at each level which automatically handles inverse depth weighting.
- Time Complexity: O(n)
- Space Complexity: O(n)
365. Water and Jug Problem
Description: You are given two jugs with capacities x and y liters. There is an infinite amount of water supply available. Determine whether it is possible to measure exactly z liters using these two jugs.
Java Solution:
public boolean canMeasureWater(int x, int y, int z) {
if (z > x + y) return false;
if (z == x || z == y || z == x + y) return true;
return z % gcd(x, y) == 0;
}
private int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
Explanation: Uses Bezout’s identity: ax + by = z has solution if and only if z is a multiple of gcd(x, y).
- Time Complexity: O(log min(x,y))
- Space Complexity: O(1)
366. Find Leaves of Binary Tree
Description: Given the root of a binary tree, collect a tree’s nodes as if you were doing this: collect all the leaf nodes, remove them, and repeat until the tree is empty.
Java Solution:
public List<List<Integer>> findLeaves(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
height(root, result);
return result;
}
private int height(TreeNode node, List<List<Integer>> result) {
if (node == null) return -1;
int level = 1 + Math.max(height(node.left, result), height(node.right, result));
if (result.size() <= level) {
result.add(new ArrayList<>());
}
result.get(level).add(node.val);
return level;
}
Explanation: Calculates height of each node from bottom up. Nodes at the same height are removed together in one iteration.
- Time Complexity: O(n)
- Space Complexity: O(h)
367. Valid Perfect Square
Description: Given a positive integer num, return true if num is a perfect square or false otherwise.
Java Solution:
public boolean isPerfectSquare(int num) {
long left = 1, right = num;
while (left <= right) {
long mid = left + (right - left) / 2;
long square = mid * mid;
if (square == num) return true;
if (square < num) left = mid + 1;
else right = mid - 1;
}
return false;
}
Explanation: Uses binary search to find if any number squared equals num, avoiding the use of built-in sqrt function.
- Time Complexity: O(log n)
- Space Complexity: O(1)
368. Largest Divisible Subset
Description: Given a set of distinct positive integers nums, return the largest subset such that every pair (Si, Sj) of elements in this subset satisfies Si % Sj = 0 or Sj % Si = 0.
Java Solution:
public List<Integer> largestDivisibleSubset(int[] nums) {
Arrays.sort(nums);
int n = nums.length;
int[] dp = new int[n], parent = new int[n];
int maxLen = 0, maxIdx = 0;
Arrays.fill(dp, 1);
Arrays.fill(parent, -1);
for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++) {
if (nums[i] % nums[j] == 0 && dp[j] + 1 > dp[i]) {
dp[i] = dp[j] + 1;
parent[i] = j;
}
}
if (dp[i] > maxLen) {
maxLen = dp[i];
maxIdx = i;
}
}
List<Integer> result = new ArrayList<>();
while (maxIdx != -1) {
result.add(nums[maxIdx]);
maxIdx = parent[maxIdx];
}
return result;
}
Explanation: Dynamic programming with parent tracking, similar to LIS but with divisibility condition.
- Time Complexity: O(n²)
- Space Complexity: O(n)
369. Plus One Linked List
Description: Given a non-negative integer represented as a linked list of digits, plus one to the integer. The digits are stored such that the most significant digit is at the head of the list.
Java Solution:
public ListNode plusOne(ListNode head) {
if (helper(head) == 0) return head;
ListNode newHead = new ListNode(1);
newHead.next = head;
return newHead;
}
private int helper(ListNode node) {
if (node == null) return 1;
int carry = helper(node.next);
int sum = node.val + carry;
node.val = sum % 10;
return sum / 10;
}
Explanation: Recursively adds 1 from the rightmost digit, propagating carry. Creates new head node if there’s a final carry.
- Time Complexity: O(n)
- Space Complexity: O(n) for recursion stack
370. Range Addition
Description: You are given an integer length and an array updates where updates[i] = [startIdxi, endIdxi, inci]. Apply all updates to return the final array.
Java Solution:
public int[] getModifiedArray(int length, int[][] updates) {
int[] result = new int[length];
for (int[] update : updates) {
result[update[0]] += update[2];
if (update[1] + 1 < length) {
result[update[1] + 1] -= update[2];
}
}
for (int i = 1; i < length; i++) {
result[i] += result[i - 1];
}
return result;
}
Explanation: Uses difference array technique: mark start with +val and end+1 with -val, then compute prefix sum.
- Time Complexity: O(n + k)
- Space Complexity: O(1)
371. Sum of Two Integers
Description: Calculate sum without using + or - operators.
Java Solution:
public int getSum(int a, int b) {
return b == 0 ? a : getSum(a ^ b, (a & b) << 1);
}
Explanation: Uses XOR for sum without carry, AND with left shift for carry. Recursively applies until no carry.
- Time Complexity: O(1)
- Space Complexity: O(1)
372. Super Pow
Description: Calculate a^b mod 1337 where b is represented as an array.
Java Solution:
public int superPow(int a, int[] b) {
int result = 1;
for (int digit : b) {
result = powmod(result, 10) * powmod(a, digit) % 1337;
}
return result;
}
private int powmod(int a, int k) {
a %= 1337;
int result = 1;
for (int i = 0; i < k; i++) {
result = result * a % 1337;
}
return result;
}
Explanation: Uses property (a^b)^c = a^(bc) and modular arithmetic to compute power efficiently.
- Time Complexity: O(n)
- Space Complexity: O(1)
373. Find K Pairs with Smallest Sums
Description: Find the k pairs with smallest sums from two sorted arrays.
Java Solution:
public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
List<List<Integer>> result = new ArrayList<>();
if (nums1.length == 0 || nums2.length == 0 || k == 0) return result;
PriorityQueue<int[]> pq = new PriorityQueue<>((a,b) -> a[0]+a[1] - b[0]-b[1]);
for (int i = 0; i < nums1.length && i < k; i++) {
pq.offer(new int[]{nums1[i], nums2[0], 0});
}
while (k-- > 0 && !pq.isEmpty()) {
int[] cur = pq.poll();
result.add(Arrays.asList(cur[0], cur[1]));
if (cur[2] < nums2.length - 1) {
pq.offer(new int[]{cur[0], nums2[cur[2]+1], cur[2]+1});
}
}
return result;
}
Explanation: Min heap with index tracking to avoid duplicate pairs.
- Time Complexity: O(k log k)
- Space Complexity: O(k)
374. Guess Number Higher or Lower
Description: Binary search guessing game.
Java Solution:
public int guessNumber(int n) {
int left = 1, right = n;
while (left <= right) {
int mid = left + (right - left) / 2;
int result = guess(mid);
if (result == 0) return mid;
if (result < 0) right = mid - 1;
else left = mid + 1;
}
return -1;
}
Explanation: Standard binary search implementation.
- Time Complexity: O(log n)
- Space Complexity: O(1)
375. Guess Number Higher or Lower II
Description: Minimize cost to guarantee a win in worst case.
Java Solution:
public int getMoneyAmount(int n) {
int[][] dp = new int[n+1][n+1];
for (int len = 2; len <= n; len++) {
for (int start = 1; start <= n - len + 1; start++) {
int end = start + len - 1;
dp[start][end] = Integer.MAX_VALUE;
for (int pivot = start; pivot < end; pivot++) {
int cost = pivot + Math.max(dp[start][pivot-1], dp[pivot+1][end]);
dp[start][end] = Math.min(dp[start][end], cost);
}
}
}
return dp[1][n];
}
Explanation: DP where dp[i][j] represents minimum cost to guarantee win for range [i,j].
- Time Complexity: O(n³)
- Space Complexity: O(n²)
376. Wiggle Subsequence
Description: Find length of longest wiggle subsequence.
Java Solution:
public int wiggleMaxLength(int[] nums) {
if (nums.length < 2) return nums.length;
int up = 1, down = 1;
for (int i = 1; i < nums.length; i++) {
if (nums[i] > nums[i-1]) up = down + 1;
else if (nums[i] < nums[i-1]) down = up + 1;
}
return Math.max(up, down);
}
Explanation: Tracks longest sequence ending with up/down move using DP.
- Time Complexity: O(n)
- Space Complexity: O(1)
377. Combination Sum IV
Description: Count number of combinations that sum to target.
Java Solution:
public int combinationSum4(int[] nums, int target) {
int[] dp = new int[target + 1];
dp[0] = 1;
for (int i = 1; i <= target; i++) {
for (int num : nums) {
if (i >= num) {
dp[i] += dp[i - num];
}
}
}
return dp[target];
}
Explanation: DP where dp[i] represents number of ways to make sum i.
- Time Complexity: O(target * n)
- Space Complexity: O(target)
378. Kth Smallest Element in a Sorted Matrix
Description: Find kth smallest in n x n sorted matrix.
Java Solution:
public int kthSmallest(int[][] matrix, int k) {
int n = matrix.length;
int left = matrix[0][0], right = matrix[n-1][n-1];
while (left < right) {
int mid = left + (right - left) / 2;
int count = 0, j = n - 1;
for (int i = 0; i < n; i++) {
while (j >= 0 && matrix[i][j] > mid) j--;
count += j + 1;
}
if (count < k) left = mid + 1;
else right = mid;
}
return left;
}
Explanation: Binary search on value range, counting elements <= mid.
- Time Complexity: O(n log(max-min))
- Space Complexity: O(1)
379. Design Phone Directory
Description: Manage available phone numbers.
Java Solution:
class PhoneDirectory {
Set<Integer> available;
public PhoneDirectory(int maxNumbers) {
available = new HashSet<>();
for (int i = 0; i < maxNumbers; i++) available.add(i);
}
public int get() {
if (available.isEmpty()) return -1;
int num = available.iterator().next();
available.remove(num);
return num;
}
public boolean check(int number) {
return available.contains(number);
}
public void release(int number) {
available.add(number);
}
}
Explanation: Uses set to track available numbers for O(1) operations.
- Time Complexity: O(1)
- Space Complexity: O(n)
380. Insert Delete GetRandom O(1)
Description: Design data structure with O(1) operations.
Java Solution:
class RandomizedSet {
Map<Integer, Integer> map = new HashMap<>();
List<Integer> list = new ArrayList<>();
Random rand = new Random();
public boolean insert(int val) {
if (map.containsKey(val)) return false;
map.put(val, list.size());
list.add(val);
return true;
}
public boolean remove(int val) {
if (!map.containsKey(val)) return false;
int idx = map.get(val);
int lastVal = list.get(list.size() - 1);
list.set(idx, lastVal);
map.put(lastVal, idx);
list.remove(list.size() - 1);
map.remove(val);
return true;
}
public int getRandom() {
return list.get(rand.nextInt(list.size()));
}
}
Explanation: HashMap for O(1) lookup, ArrayList for O(1) random access.
- Time Complexity: O(1)
- Space Complexity: O(n)
381. Insert Delete GetRandom O(1) - Duplicates
Description: Same as 380 but allowing duplicates.
Java Solution:
class RandomizedCollection {
Map<Integer, Set<Integer>> map = new HashMap<>();
List<Integer> list = new ArrayList<>();
Random rand = new Random();
public boolean insert(int val) {
boolean notPresent = !map.containsKey(val);
map.putIfAbsent(val, new HashSet<>());
map.get(val).add(list.size());
list.add(val);
return notPresent;
}
public boolean remove(int val) {
if (!map.containsKey(val)) return false;
int idx = map.get(val).iterator().next();
map.get(val).remove(idx);
int lastVal = list.get(list.size() - 1);
list.set(idx, lastVal);
map.get(lastVal).add(idx);
map.get(lastVal).remove(list.size() - 1);
list.remove(list.size() - 1);
if (map.get(val).isEmpty()) map.remove(val);
return true;
}
public int getRandom() {
return list.get(rand.nextInt(list.size()));
}
}
Explanation: Map stores set of indices for each value to handle duplicates.
- Time Complexity: O(1)
- Space Complexity: O(n)
382. Linked List Random Node
Description: Get random node from linked list with uniform probability.
Java Solution:
class Solution {
ListNode head;
Random rand = new Random();
public Solution(ListNode head) {
this.head = head;
}
public int getRandom() {
ListNode cur = head;
int result = cur.val, count = 1;
while (cur != null) {
if (rand.nextInt(count) == 0) result = cur.val;
count++;
cur = cur.next;
}
return result;
}
}
Explanation: Reservoir sampling algorithm: select node i with probability 1/i.
- Time Complexity: O(n)
- Space Complexity: O(1)
383. Ransom Note
Description: Check if ransom note can be constructed from magazine.
Java Solution:
public boolean canConstruct(String ransomNote, String magazine) {
int[] count = new int[26];
for (char c : magazine.toCharArray()) count[c - 'a']++;
for (char c : ransomNote.toCharArray()) {
if (--count[c - 'a'] < 0) return false;
}
return true;
}
Explanation: Count character frequencies in magazine, decrement for ransom note characters.
- Time Complexity: O(n)
- Space Complexity: O(1)
384. Shuffle an Array
Description: Shuffle array uniformly at random.
Java Solution:
class Solution {
int[] original, array;
Random rand = new Random();
public Solution(int[] nums) {
original = nums.clone();
array = nums;
}
public int[] reset() {
return original;
}
public int[] shuffle() {
for (int i = array.length - 1; i > 0; i--) {
int j = rand.nextInt(i + 1);
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
}
Explanation: Fisher-Yates shuffle algorithm for uniform random permutation.
- Time Complexity: O(n)
- Space Complexity: O(n)
385. Mini Parser
Description: Parse nested integer from string representation.
Java Solution:
public NestedInteger deserialize(String s) {
if (s.charAt(0) != '[') return new NestedInteger(Integer.parseInt(s));
Stack<NestedInteger> stack = new Stack<>();
NestedInteger curr = null;
int left = 0;
for (int right = 0; right < s.length(); right++) {
char ch = s.charAt(right);
if (ch == '[') {
if (curr != null) stack.push(curr);
curr = new NestedInteger();
left = right + 1;
} else if (ch == ']') {
String num = s.substring(left, right);
if (!num.isEmpty()) curr.add(new NestedInteger(Integer.parseInt(num)));
if (!stack.isEmpty()) {
NestedInteger parent = stack.pop();
parent.add(curr);
curr = parent;
}
left = right + 1;
} else if (ch == ',') {
if (s.charAt(right - 1) != ']') {
String num = s.substring(left, right);
curr.add(new NestedInteger(Integer.parseInt(num)));
}
left = right + 1;
}
}
return curr;
}
Explanation: Stack-based parsing of nested structures.
- Time Complexity: O(n)
- Space Complexity: O(n)
386. Lexicographical Numbers
Description: Return numbers 1 to n in lexicographical order.
Java Solution:
public List<Integer> lexicalOrder(int n) {
List<Integer> result = new ArrayList<>();
int curr = 1;
for (int i = 0; i < n; i++) {
result.add(curr);
if (curr * 10 <= n) {
curr *= 10;
} else {
if (curr >= n) curr /= 10;
curr++;
while (curr % 10 == 0) curr /= 10;
}
}
return result;
}
Explanation: Iteratively generates lexicographical order without sorting.
- Time Complexity: O(n)
- Space Complexity: O(1)
387. First Unique Character in a String
Description: Find first non-repeating character index.
Java Solution:
public int firstUniqChar(String s) {
int[] count = new int[26];
for (char c : s.toCharArray()) count[c - 'a']++;
for (int i = 0; i < s.length(); i++) {
if (count[s.charAt(i) - 'a'] == 1) return i;
}
return -1;
}
Explanation: Two-pass: count frequencies, then find first character with count 1.
- Time Complexity: O(n)
- Space Complexity: O(1)
388. Longest Absolute File Path
Description: Find longest absolute path to file in filesystem.
Java Solution:
public int lengthLongestPath(String input) {
String[] lines = input.split("\n");
int[] lengths = new int[lines.length + 1];
int maxLen = 0;
for (String line : lines) {
int level = line.lastIndexOf("\t") + 1;
int len = line.length() - level;
if (line.contains(".")) {
maxLen = Math.max(maxLen, lengths[level] + len);
} else {
lengths[level + 1] = lengths[level] + len + 1;
}
}
return maxLen;
}
Explanation: Tracks cumulative path length at each directory level.
- Time Complexity: O(n)
- Space Complexity: O(n)
389. Find the Difference
Description: Find the extra character added to string t.
Java Solution:
public char findTheDifference(String s, String t) {
int sum = 0;
for (char c : t.toCharArray()) sum += c;
for (char c : s.toCharArray()) sum -= c;
return (char) sum;
}
Explanation: Sum of ASCII values difference reveals the extra character.
- Time Complexity: O(n)
- Space Complexity: O(1)
390. Elimination Game
Description: Find last remaining number after elimination process.
Java Solution:
public int lastRemaining(int n) {
int head = 1, step = 1, remaining = n;
boolean left = true;
while (remaining > 1) {
if (left || remaining % 2 == 1) head += step;
remaining /= 2;
step *= 2;
left = !left;
}
return head;
}
Explanation: Tracks head position and step size through elimination rounds.
- Time Complexity: O(log n)
- Space Complexity: O(1)
391. Perfect Rectangle
Description: Given an array rectangles where rectangles[i] = [xi, yi, ai, bi] represents an axis-aligned rectangle, return true if all the rectangles together form an exact cover of a rectangular region.
Java Solution:
public boolean isRectangleCover(int[][] rectangles) {
int x1 = Integer.MAX_VALUE, y1 = Integer.MAX_VALUE;
int x2 = Integer.MIN_VALUE, y2 = Integer.MIN_VALUE;
Set<String> set = new HashSet<>();
int area = 0;
for (int[] rect : rectangles) {
x1 = Math.min(x1, rect[0]);
y1 = Math.min(y1, rect[1]);
x2 = Math.max(x2, rect[2]);
y2 = Math.max(y2, rect[3]);
area += (rect[2] - rect[0]) * (rect[3] - rect[1]);
String[] corners = {
rect[0] + " " + rect[1],
rect[0] + " " + rect[3],
rect[2] + " " + rect[1],
rect[2] + " " + rect[3]
};
for (String corner : corners) {
if (!set.add(corner)) set.remove(corner);
}
}
if (set.size() != 4 || !set.contains(x1 + " " + y1) ||
!set.contains(x1 + " " + y2) || !set.contains(x2 + " " + y1) ||
!set.contains(x2 + " " + y2)) return false;
return area == (x2 - x1) * (y2 - y1);
}
Explanation: Checks if sum of areas equals bounding rectangle area and only 4 corners remain (each internal corner appears even times).
- Time Complexity: O(n)
- Space Complexity: O(n)
392. Is Subsequence
Description: Given two strings s and t, return true if s is a subsequence of t, or false otherwise.
Java Solution:
public boolean isSubsequence(String s, String t) {
int i = 0;
for (int j = 0; j < t.length() && i < s.length(); j++) {
if (s.charAt(i) == t.charAt(j)) i++;
}
return i == s.length();
}
Explanation: Two pointers approach: advance in s only when characters match.
- Time Complexity: O(n)
- Space Complexity: O(1)
393. UTF-8 Validation
Description: Given an integer array data representing bytes, return true if it is a valid UTF-8 encoding.
Java Solution:
public boolean validUtf8(int[] data) {
int count = 0;
for (int num : data) {
if (count == 0) {
if ((num >> 5) == 0b110) count = 1;
else if ((num >> 4) == 0b1110) count = 2;
else if ((num >> 3) == 0b11110) count = 3;
else if ((num >> 7) != 0) return false;
} else {
if ((num >> 6) != 0b10) return false;
count--;
}
}
return count == 0;
}
Explanation: Validates UTF-8 by checking byte patterns for 1-4 byte characters.
- Time Complexity: O(n)
- Space Complexity: O(1)
394. Decode String
Description: Given an encoded string like ‘3[a2[c]]’, return the decoded string ‘accaccacc’.
Java Solution:
public String decodeString(String s) {
Stack<Integer> countStack = new Stack<>();
Stack<String> stringStack = new Stack<>();
String current = "";
int k = 0;
for (char ch : s.toCharArray()) {
if (Character.isDigit(ch)) {
k = k * 10 + (ch - '0');
} else if (ch == '[') {
countStack.push(k);
stringStack.push(current);
current = "";
k = 0;
} else if (ch == ']') {
StringBuilder temp = new StringBuilder(stringStack.pop());
int repeatTimes = countStack.pop();
for (int i = 0; i < repeatTimes; i++) {
temp.append(current);
}
current = temp.toString();
} else {
current += ch;
}
}
return current;
}
Explanation: Uses two stacks to track counts and strings, building the result by expanding brackets.
- Time Complexity: O(n)
- Space Complexity: O(n)
395. Longest Substring with At Least K Repeating Characters
Description: Find the length of the longest substring where every character appears at least k times.
Java Solution:
public int longestSubstring(String s, int k) {
if (s == null || s.length() < k) return 0;
int[] count = new int[26];
for (char c : s.toCharArray()) count[c - 'a']++;
for (int i = 0; i < s.length(); i++) {
if (count[s.charAt(i) - 'a'] < k) {
int left = longestSubstring(s.substring(0, i), k);
int right = longestSubstring(s.substring(i + 1), k);
return Math.max(left, right);
}
}
return s.length();
}
Explanation: Divides string at characters with count < k, recursively solving subproblems.
- Time Complexity: O(n)
- Space Complexity: O(n)
396. Rotate Function
Description: Given array A, calculate max value of F(k) where F(k) = sum(i * A[(i+k) % n]).
Java Solution:
public int maxRotateFunction(int[] nums) {
int n = nums.length, sum = 0, f = 0;
for (int i = 0; i < n; i++) {
sum += nums[i];
f += i * nums[i];
}
int max = f;
for (int i = n - 1; i >= 0; i--) {
f = f + sum - n * nums[i];
max = Math.max(max, f);
}
return max;
}
Explanation: Uses math formula: F(k) = F(k-1) + sum - n*A[n-k] to avoid recalculation.
- Time Complexity: O(n)
- Space Complexity: O(1)
397. Integer Replacement
Description: Given integer n, return minimum steps to reduce it to 1 using n-1, n+1, or n/2 operations.
Java Solution:
public int integerReplacement(int n) {
int count = 0;
long num = n;
while (num != 1) {
if (num % 2 == 0) {
num /= 2;
} else if (num == 3 || Integer.bitCount((int)(num - 1)) > Integer.bitCount((int)(num + 1))) {
num--;
} else {
num++;
}
count++;
}
return count;
}
Explanation: Greedy approach: divide by 2 when even, otherwise choose +1 or -1 based on bit count.
- Time Complexity: O(log n)
- Space Complexity: O(1)
398. Random Pick Index
Description: Given array with duplicates, return random index of target value with uniform probability.
Java Solution:
class Solution {
int[] nums;
Random rand;
public Solution(int[] nums) {
this.nums = nums;
rand = new Random();
}
public int pick(int target) {
int result = -1, count = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != target) continue;
if (rand.nextInt(++count) == 0) result = i;
}
return result;
}
}
Explanation: Reservoir sampling: each matching index has 1/count probability of being selected.
- Time Complexity: O(n)
- Space Complexity: O(1)
399. Evaluate Division
Description: Given equations a/b=k, answer queries x/y by finding the value or -1 if not determinable.
Java Solution:
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
Map<String, Map<String, Double>> graph = new HashMap<>();
for (int i = 0; i < equations.size(); i++) {
String a = equations.get(i).get(0), b = equations.get(i).get(1);
graph.putIfAbsent(a, new HashMap<>());
graph.putIfAbsent(b, new HashMap<>());
graph.get(a).put(b, values[i]);
graph.get(b).put(a, 1.0 / values[i]);
}
double[] result = new double[queries.size()];
for (int i = 0; i < queries.size(); i++) {
result[i] = dfs(graph, queries.get(i).get(0), queries.get(i).get(1), new HashSet<>(), 1.0);
}
return result;
}
private double dfs(Map<String, Map<String, Double>> graph, String start, String end, Set<String> visited, double value) {
if (!graph.containsKey(start) || !graph.containsKey(end)) return -1.0;
if (start.equals(end)) return value;
visited.add(start);
for (String next : graph.get(start).keySet()) {
if (visited.contains(next)) continue;
double result = dfs(graph, next, end, visited, value * graph.get(start).get(next));
if (result != -1.0) return result;
}
return -1.0;
}
Explanation: Builds directed weighted graph, uses DFS to find path and multiply edge weights.
- Time Complexity: O(V + E) per query
- Space Complexity: O(V + E)
400. Nth Digit
Description: Find the nth digit in the sequence: 123456789101112131415…
Java Solution:
public int findNthDigit(int n) {
long len = 1, count = 9, start = 1;
while (n > len * count) {
n -= len * count;
len++;
count *= 10;
start *= 10;
}
start += (n - 1) / len;
String s = Long.toString(start);
return Character.getNumericValue(s.charAt((int)((n - 1) % len)));
}
Explanation: Calculates which number contains nth digit, then extracts the specific digit.
- Time Complexity: O(log n)
- Space Complexity: O(1)
401. Binary Watch
Description: Return all possible times a binary watch could represent given number of LEDs on.
Java Solution:
public List<String> readBinaryWatch(int turnedOn) {
List<String> result = new ArrayList<>();
for (int h = 0; h < 12; h++) {
for (int m = 0; m < 60; m++) {
if (Integer.bitCount(h) + Integer.bitCount(m) == turnedOn) {
result.add(String.format("%d:%02d", h, m));
}
}
}
return result;
}
Explanation: Iterate all possible times. Count bits in hours and minutes. Add if total bits equals turnedOn.
- Time Complexity: O(1)
- Space Complexity: O(1)
402. Remove K Digits
Description: Remove k digits from number to get smallest possible result.
Java Solution:
public String removeKdigits(String num, int k) {
Deque<Character> stack = new ArrayDeque<>();
for (char c : num.toCharArray()) {
while (!stack.isEmpty() && k > 0 && stack.peek() > c) {
stack.pop();
k--;
}
stack.push(c);
}
while (k-- > 0) stack.pop();
StringBuilder sb = new StringBuilder();
while (!stack.isEmpty()) sb.append(stack.pollLast());
while (sb.length() > 1 && sb.charAt(0) == '0') sb.deleteCharAt(0);
return sb.length() == 0 ? "0" : sb.toString();
}
Explanation: Use monotonic stack. Remove larger digits when smaller digit comes. Greedily keep smaller digits at front.
- Time Complexity: O(n)
- Space Complexity: O(n)
403. Frog Jump
Description: Determine if frog can cross river by jumping on stones.
Java Solution:
public boolean canCross(int[] stones) {
Map<Integer, Set<Integer>> dp = new HashMap<>();
for (int stone : stones) dp.put(stone, new HashSet<>());
dp.get(0).add(0);
for (int stone : stones) {
for (int k : dp.get(stone)) {
for (int step = k - 1; step <= k + 1; step++) {
if (step > 0 && dp.containsKey(stone + step)) {
dp.get(stone + step).add(step);
}
}
}
}
return !dp.get(stones[stones.length - 1]).isEmpty();
}
Explanation: Track possible jump sizes at each stone. From each stone, try jumps of k-1, k, k+1. Check if last stone is reachable.
- Time Complexity: O(n²)
- Space Complexity: O(n²)
404. Sum of Left Leaves
Description: Find sum of all left leaves in binary tree.
Java Solution:
public int sumOfLeftLeaves(TreeNode root) {
if (root == null) return 0;
int sum = 0;
if (root.left != null && root.left.left == null && root.left.right == null) {
sum = root.left.val;
}
return sum + sumOfLeftLeaves(root.left) + sumOfLeftLeaves(root.right);
}
Explanation: Recursively traverse. Add value if left child is a leaf. Continue with both subtrees.
- Time Complexity: O(n)
- Space Complexity: O(h)
405. Convert a Number to Hexadecimal
Description: Convert integer to hexadecimal string (two’s complement for negatives).
Java Solution:
public String toHex(int num) {
if (num == 0) return "0";
char[] hex = "0123456789abcdef".toCharArray();
StringBuilder sb = new StringBuilder();
while (num != 0) {
sb.insert(0, hex[num & 15]);
num >>>= 4;
}
return sb.toString();
}
Explanation: Extract 4 bits at a time using AND with 15. Use unsigned right shift for negative numbers.
- Time Complexity: O(1)
- Space Complexity: O(1)
406. Queue Reconstruction by Height
Description: Reconstruct queue where each person [h, k] has height h with k people of >= height in front.
Java Solution:
public int[][] reconstructQueue(int[][] people) {
Arrays.sort(people, (a, b) -> a[0] != b[0] ? b[0] - a[0] : a[1] - b[1]);
List<int[]> result = new ArrayList<>();
for (int[] p : people) {
result.add(p[1], p);
}
return result.toArray(new int[people.length][]);
}
Explanation: Sort by height descending, then by k ascending. Insert each person at index k. Taller people already placed.
- Time Complexity: O(n²)
- Space Complexity: O(n)
407. Trapping Rain Water II
Description: Calculate water trapped in 2D elevation map.
Java Solution:
public int trapRainWater(int[][] heightMap) {
int m = heightMap.length, n = heightMap[0].length;
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[2] - b[2]);
boolean[][] visited = new boolean[m][n];
for (int i = 0; i < m; i++) {
pq.offer(new int[]{i, 0, heightMap[i][0]});
pq.offer(new int[]{i, n-1, heightMap[i][n-1]});
visited[i][0] = visited[i][n-1] = true;
}
for (int j = 1; j < n-1; j++) {
pq.offer(new int[]{0, j, heightMap[0][j]});
pq.offer(new int[]{m-1, j, heightMap[m-1][j]});
visited[0][j] = visited[m-1][j] = true;
}
int water = 0;
int[][] dirs = {{0,1},{0,-1},{1,0},{-1,0}};
while (!pq.isEmpty()) {
int[] cell = pq.poll();
for (int[] d : dirs) {
int ni = cell[0] + d[0], nj = cell[1] + d[1];
if (ni >= 0 && ni < m && nj >= 0 && nj < n && !visited[ni][nj]) {
visited[ni][nj] = true;
water += Math.max(0, cell[2] - heightMap[ni][nj]);
pq.offer(new int[]{ni, nj, Math.max(cell[2], heightMap[ni][nj])});
}
}
}
return water;
}
Explanation: Use min-heap starting from borders. Process cells in height order. Water at each cell bounded by minimum surrounding height.
- Time Complexity: O(mn log mn)
- Space Complexity: O(mn)
408. Valid Word Abbreviation
Description: Check if abbreviation matches word.
Java Solution:
public boolean validWordAbbreviation(String word, String abbr) {
int i = 0, j = 0;
while (i < word.length() && j < abbr.length()) {
if (Character.isDigit(abbr.charAt(j))) {
if (abbr.charAt(j) == '0') return false;
int num = 0;
while (j < abbr.length() && Character.isDigit(abbr.charAt(j))) {
num = num * 10 + (abbr.charAt(j++) - '0');
}
i += num;
} else {
if (word.charAt(i++) != abbr.charAt(j++)) return false;
}
}
return i == word.length() && j == abbr.length();
}
Explanation: Two pointers. If digit, skip that many chars in word (no leading zeros). If letter, must match exactly.
- Time Complexity: O(n)
- Space Complexity: O(1)
409. Longest Palindrome
Description: Find length of longest palindrome that can be built from given letters.
Java Solution:
public int longestPalindrome(String s) {
int[] count = new int[128];
for (char c : s.toCharArray()) count[c]++;
int length = 0;
boolean hasOdd = false;
for (int c : count) {
length += c / 2 * 2;
if (c % 2 == 1) hasOdd = true;
}
return hasOdd ? length + 1 : length;
}
Explanation: Count each character. Use pairs for palindrome. Can add one odd character in middle.
- Time Complexity: O(n)
- Space Complexity: O(1)
410. Split Array Largest Sum
Description: Split array into m subarrays minimizing largest sum.
Java Solution:
public int splitArray(int[] nums, int m) {
long left = 0, right = 0;
for (int num : nums) {
left = Math.max(left, num);
right += num;
}
while (left < right) {
long mid = left + (right - left) / 2;
if (canSplit(nums, m, mid)) right = mid;
else left = mid + 1;
}
return (int) left;
}
private boolean canSplit(int[] nums, int m, long maxSum) {
int count = 1;
long sum = 0;
for (int num : nums) {
if (sum + num > maxSum) {
count++;
sum = num;
} else sum += num;
}
return count <= m;
}
Explanation: Binary search on answer. For each candidate max sum, check if array can be split into m or fewer parts.
- Time Complexity: O(n log sum)
- Space Complexity: O(1)
411. Minimum Unique Word Abbreviation
Description: Find shortest abbreviation that doesn’t match any word in dictionary.
Java Solution:
public String minAbbreviation(String target, String[] dictionary) {
List<Integer> masks = new ArrayList<>();
int n = target.length();
for (String word : dictionary) {
if (word.length() == n) {
int mask = 0;
for (int i = 0; i < n; i++) {
if (word.charAt(i) != target.charAt(i)) mask |= (1 << i);
}
masks.add(mask);
}
}
if (masks.isEmpty()) return String.valueOf(n);
String result = target;
for (int abbr = 1; abbr < (1 << n); abbr++) {
boolean valid = true;
for (int mask : masks) {
if ((abbr & mask) == 0) { valid = false; break; }
}
if (valid) {
String candidate = toAbbr(target, abbr);
if (candidate.length() < result.length()) result = candidate;
}
}
return result;
}
private String toAbbr(String s, int mask) {
StringBuilder sb = new StringBuilder();
int count = 0;
for (int i = 0; i < s.length(); i++) {
if ((mask & (1 << i)) != 0) {
if (count > 0) { sb.append(count); count = 0; }
sb.append(s.charAt(i));
} else count++;
}
if (count > 0) sb.append(count);
return sb.toString();
}
Explanation: Use bitmask to represent abbreviation. For each mask, check it differs from all dictionary words at some kept position.
- Time Complexity: O(2^n × d)
- Space Complexity: O(d)
412. Fizz Buzz
Description: Return array with Fizz for multiples of 3, Buzz for 5, FizzBuzz for both.
Java Solution:
public List<String> fizzBuzz(int n) {
List<String> result = new ArrayList<>();
for (int i = 1; i <= n; i++) {
if (i % 15 == 0) result.add("FizzBuzz");
else if (i % 3 == 0) result.add("Fizz");
else if (i % 5 == 0) result.add("Buzz");
else result.add(String.valueOf(i));
}
return result;
}
Explanation: Check divisibility by 15 first, then 3, then 5. Add corresponding string to result.
- Time Complexity: O(n)
- Space Complexity: O(1)
413. Arithmetic Slices
Description: Count arithmetic slices in array (at least 3 elements).
Java Solution:
public int numberOfArithmeticSlices(int[] nums) {
int count = 0, curr = 0;
for (int i = 2; i < nums.length; i++) {
if (nums[i] - nums[i-1] == nums[i-1] - nums[i-2]) {
curr++;
count += curr;
} else curr = 0;
}
return count;
}
Explanation: Track current arithmetic sequence length. Each extension adds curr new slices. Reset on break.
- Time Complexity: O(n)
- Space Complexity: O(1)
414. Third Maximum Number
Description: Return third distinct maximum. If not exist, return maximum.
Java Solution:
public int thirdMax(int[] nums) {
long first = Long.MIN_VALUE, second = Long.MIN_VALUE, third = Long.MIN_VALUE;
for (int num : nums) {
if (num == first || num == second || num == third) continue;
if (num > first) {
third = second; second = first; first = num;
} else if (num > second) {
third = second; second = num;
} else if (num > third) {
third = num;
}
}
return third == Long.MIN_VALUE ? (int) first : (int) third;
}
Explanation: Track top 3 distinct values. Update accordingly. If third not found, return first.
- Time Complexity: O(n)
- Space Complexity: O(1)
415. Add Strings
Description: Add two numbers represented as strings.
Java Solution:
public String addStrings(String num1, String num2) {
StringBuilder sb = new StringBuilder();
int i = num1.length() - 1, j = num2.length() - 1, carry = 0;
while (i >= 0 || j >= 0 || carry > 0) {
int sum = carry;
if (i >= 0) sum += num1.charAt(i--) - '0';
if (j >= 0) sum += num2.charAt(j--) - '0';
sb.insert(0, sum % 10);
carry = sum / 10;
}
return sb.toString();
}
Explanation: Add digits from right to left with carry. Handle different lengths. Build result string.
- Time Complexity: O(max(n, m))
- Space Complexity: O(max(n, m))
416. Partition Equal Subset Sum
Description: Determine if array can be partitioned into two equal sum subsets.
Java Solution:
public boolean canPartition(int[] nums) {
int sum = 0;
for (int num : nums) sum += num;
if (sum % 2 != 0) return false;
int target = sum / 2;
boolean[] dp = new boolean[target + 1];
dp[0] = true;
for (int num : nums) {
for (int j = target; j >= num; j--) {
dp[j] = dp[j] || dp[j - num];
}
}
return dp[target];
}
Explanation: 0/1 knapsack variant. Check if subset sum equals half of total. Use DP to track achievable sums.
- Time Complexity: O(n × sum)
- Space Complexity: O(sum)
417. Pacific Atlantic Water Flow
Description: Find cells where water can flow to both Pacific and Atlantic oceans.
Java Solution:
public List<List<Integer>> pacificAtlantic(int[][] heights) {
int m = heights.length, n = heights[0].length;
boolean[][] pacific = new boolean[m][n];
boolean[][] atlantic = new boolean[m][n];
for (int i = 0; i < m; i++) {
dfs(heights, pacific, i, 0);
dfs(heights, atlantic, i, n - 1);
}
for (int j = 0; j < n; j++) {
dfs(heights, pacific, 0, j);
dfs(heights, atlantic, m - 1, j);
}
List<List<Integer>> result = new ArrayList<>();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (pacific[i][j] && atlantic[i][j])
result.add(Arrays.asList(i, j));
}
}
return result;
}
private void dfs(int[][] heights, boolean[][] visited, int i, int j) {
visited[i][j] = true;
int[][] dirs = {{0,1},{0,-1},{1,0},{-1,0}};
for (int[] d : dirs) {
int ni = i + d[0], nj = j + d[1];
if (ni >= 0 && ni < heights.length && nj >= 0 && nj < heights[0].length
&& !visited[ni][nj] && heights[ni][nj] >= heights[i][j]) {
dfs(heights, visited, ni, nj);
}
}
}
Explanation: DFS from ocean edges inward. Water flows uphill from ocean perspective. Intersection of both reaches is answer.
- Time Complexity: O(mn)
- Space Complexity: O(mn)
418. Sentence Screen Fitting
Description: Count how many times sentence fits on screen with given rows and cols.
Java Solution:
public int wordsTyping(String[] sentence, int rows, int cols) {
String s = String.join(" ", sentence) + " ";
int len = s.length(), count = 0;
for (int i = 0; i < rows; i++) {
count += cols;
if (s.charAt(count % len) == ' ') {
count++;
} else {
while (count > 0 && s.charAt((count - 1) % len) != ' ') {
count--;
}
}
}
return count / len;
}
Explanation: Concatenate sentence with spaces. Track position in virtual infinite string. Adjust for word boundaries.
- Time Complexity: O(rows × avg_word_length)
- Space Complexity: O(sentence_length)
419. Battleships in a Board
Description: Count battleships on board (only count top-left of each ship).
Java Solution:
public int countBattleships(char[][] board) {
int count = 0;
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] == 'X') {
if (i > 0 && board[i-1][j] == 'X') continue;
if (j > 0 && board[i][j-1] == 'X') continue;
count++;
}
}
}
return count;
}
Explanation: Only count X if no X above or to the left. This counts each ship exactly once at its top-left corner.
- Time Complexity: O(mn)
- Space Complexity: O(1)
420. Strong Password Checker
Description: Return minimum changes to make password strong.
Java Solution:
public int strongPasswordChecker(String password) {
int n = password.length();
boolean hasLower = false, hasUpper = false, hasDigit = false;
for (char c : password.toCharArray()) {
if (Character.isLowerCase(c)) hasLower = true;
else if (Character.isUpperCase(c)) hasUpper = true;
else if (Character.isDigit(c)) hasDigit = true;
}
int missing = (hasLower ? 0 : 1) + (hasUpper ? 0 : 1) + (hasDigit ? 0 : 1);
if (n < 6) return Math.max(6 - n, missing);
int replace = 0, oneMod = 0, twoMod = 0;
for (int i = 2; i < n; ) {
if (password.charAt(i) == password.charAt(i-1) && password.charAt(i-1) == password.charAt(i-2)) {
int len = 2;
while (i < n && password.charAt(i) == password.charAt(i-1)) { len++; i++; }
replace += len / 3;
if (len % 3 == 0) oneMod++;
else if (len % 3 == 1) twoMod++;
} else i++;
}
if (n <= 20) return Math.max(replace, missing);
int delete = n - 20;
replace -= Math.min(delete, oneMod);
replace -= Math.min(Math.max(delete - oneMod, 0), twoMod * 2) / 2;
replace -= Math.max(delete - oneMod - 2 * twoMod, 0) / 3;
return delete + Math.max(replace, missing);
}
Explanation: Handle length < 6, 6-20, and > 20 separately. Track repeating sequences. Optimize deletions to reduce replacements.
- Time Complexity: O(n)
- Space Complexity: O(1)
421. Maximum XOR of Two Numbers in an Array
Description: Find maximum XOR of any two numbers in array.
Java Solution:
public int findMaximumXOR(int[] nums) {
int maxXor = 0, mask = 0;
for (int i = 31; i >= 0; i--) {
mask |= (1 << i);
Set<Integer> prefixes = new HashSet<>();
for (int num : nums) prefixes.add(num & mask);
int candidate = maxXor | (1 << i);
for (int prefix : prefixes) {
if (prefixes.contains(prefix ^ candidate)) {
maxXor = candidate;
break;
}
}
}
return maxXor;
}
Explanation: Build XOR bit by bit from MSB. For each bit, check if setting it to 1 is achievable using prefix XOR property.
- Time Complexity: O(32n)
- Space Complexity: O(n)
422. Valid Word Square
Description: Check if words form a valid word square (row i equals column i).
Java Solution:
public boolean validWordSquare(List<String> words) {
for (int i = 0; i < words.size(); i++) {
for (int j = 0; j < words.get(i).length(); j++) {
if (j >= words.size() || i >= words.get(j).length() ||
words.get(i).charAt(j) != words.get(j).charAt(i)) {
return false;
}
}
}
return true;
}
Explanation: Check each position (i,j) equals position (j,i). Handle bounds for non-square cases.
- Time Complexity: O(n × m)
- Space Complexity: O(1)
423. Reconstruct Original Digits from English
Description: Reconstruct digits from shuffled English representation.
Java Solution:
public String originalDigits(String s) {
int[] count = new int[10];
int[] charCount = new int[26];
for (char c : s.toCharArray()) charCount[c - 'a']++;
count[0] = charCount['z' - 'a'];
count[2] = charCount['w' - 'a'];
count[4] = charCount['u' - 'a'];
count[6] = charCount['x' - 'a'];
count[8] = charCount['g' - 'a'];
count[1] = charCount['o' - 'a'] - count[0] - count[2] - count[4];
count[3] = charCount['h' - 'a'] - count[8];
count[5] = charCount['f' - 'a'] - count[4];
count[7] = charCount['s' - 'a'] - count[6];
count[9] = charCount['i' - 'a'] - count[5] - count[6] - count[8];
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= 9; i++) {
for (int j = 0; j < count[i]; j++) sb.append(i);
}
return sb.toString();
}
Explanation: Use unique letters: z(0), w(2), u(4), x(6), g(8). Then deduce others from remaining counts.
- Time Complexity: O(n)
- Space Complexity: O(1)
424. Longest Repeating Character Replacement
Description: Find longest substring with at most k character replacements.
Java Solution:
public int characterReplacement(String s, int k) {
int[] count = new int[26];
int maxCount = 0, maxLength = 0;
int left = 0;
for (int right = 0; right < s.length(); right++) {
maxCount = Math.max(maxCount, ++count[s.charAt(right) - 'A']);
while (right - left + 1 - maxCount > k) {
count[s.charAt(left++) - 'A']--;
}
maxLength = Math.max(maxLength, right - left + 1);
}
return maxLength;
}
Explanation: Sliding window. Track max frequency in window. Window valid if length - maxFreq <= k.
- Time Complexity: O(n)
- Space Complexity: O(1)
425. Word Squares
Description: Find all word squares from given words.
Java Solution:
public List<List<String>> wordSquares(String[] words) {
List<List<String>> result = new ArrayList<>();
Map<String, List<String>> prefixMap = new HashMap<>();
for (String word : words) {
for (int i = 0; i <= word.length(); i++) {
prefixMap.computeIfAbsent(word.substring(0, i), k -> new ArrayList<>()).add(word);
}
}
backtrack(words[0].length(), new ArrayList<>(), prefixMap, result);
return result;
}
private void backtrack(int n, List<String> square, Map<String, List<String>> map, List<List<String>> result) {
if (square.size() == n) {
result.add(new ArrayList<>(square));
return;
}
int idx = square.size();
StringBuilder prefix = new StringBuilder();
for (String word : square) prefix.append(word.charAt(idx));
for (String candidate : map.getOrDefault(prefix.toString(), new ArrayList<>())) {
square.add(candidate);
backtrack(n, square, map, result);
square.remove(square.size() - 1);
}
}
Explanation: Build prefix map. Backtrack row by row. Next row must match column prefix formed by previous rows.
- Time Complexity: O(n × 26^n)
- Space Complexity: O(n × m)
426. Convert Binary Search Tree to Sorted Doubly Linked List
Description: Convert BST to sorted circular doubly linked list in-place.
Java Solution:
Node first = null, last = null;
public Node treeToDoublyList(Node root) {
if (root == null) return null;
inorder(root);
first.left = last;
last.right = first;
return first;
}
private void inorder(Node node) {
if (node == null) return;
inorder(node.left);
if (last != null) {
last.right = node;
node.left = last;
} else first = node;
last = node;
inorder(node.right);
}
Explanation: Inorder traversal visits nodes in sorted order. Link consecutive nodes. Connect first and last for circular.
- Time Complexity: O(n)
- Space Complexity: O(h)
427. Construct Quad-Tree
Description: Construct quad-tree from 2D grid.
Java Solution:
public Node construct(int[][] grid) {
return build(grid, 0, 0, grid.length);
}
private Node build(int[][] grid, int r, int c, int len) {
if (len == 1) return new Node(grid[r][c] == 1, true);
int half = len / 2;
Node topLeft = build(grid, r, c, half);
Node topRight = build(grid, r, c + half, half);
Node bottomLeft = build(grid, r + half, c, half);
Node bottomRight = build(grid, r + half, c + half, half);
if (topLeft.isLeaf && topRight.isLeaf && bottomLeft.isLeaf && bottomRight.isLeaf
&& topLeft.val == topRight.val && topRight.val == bottomLeft.val && bottomLeft.val == bottomRight.val) {
return new Node(topLeft.val, true);
}
return new Node(false, false, topLeft, topRight, bottomLeft, bottomRight);
}
Explanation: Recursively divide grid into quadrants. Merge if all children are leaves with same value.
- Time Complexity: O(n² log n)
- Space Complexity: O(log n)
428. Serialize and Deserialize N-ary Tree
Description: Serialize and deserialize N-ary tree.
Java Solution:
public String serialize(Node root) {
if (root == null) return "";
StringBuilder sb = new StringBuilder();
serialize(root, sb);
return sb.toString();
}
private void serialize(Node node, StringBuilder sb) {
sb.append(node.val).append(" ").append(node.children.size()).append(" ");
for (Node child : node.children) serialize(child, sb);
}
public Node deserialize(String data) {
if (data.isEmpty()) return null;
Queue<String> queue = new LinkedList<>(Arrays.asList(data.split(" ")));
return deserialize(queue);
}
private Node deserialize(Queue<String> queue) {
int val = Integer.parseInt(queue.poll());
int size = Integer.parseInt(queue.poll());
Node node = new Node(val, new ArrayList<>());
for (int i = 0; i < size; i++) node.children.add(deserialize(queue));
return node;
}
Explanation: Store value and children count. Recursively serialize children. Deserialize by reading count and reconstructing.
- Time Complexity: O(n)
- Space Complexity: O(n)
429. N-ary Tree Level Order Traversal
Description: Return level order traversal of N-ary tree.
Java Solution:
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) return result;
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> level = new ArrayList<>();
for (int i = 0; i < size; i++) {
Node node = queue.poll();
level.add(node.val);
queue.addAll(node.children);
}
result.add(level);
}
return result;
}
Explanation: BFS level by level. Process all nodes at current level, add their children for next level.
- Time Complexity: O(n)
- Space Complexity: O(n)
430. Flatten a Multilevel Doubly Linked List
Description: Flatten multilevel doubly linked list with child pointers.
Java Solution:
public Node flatten(Node head) {
if (head == null) return null;
Node curr = head;
while (curr != null) {
if (curr.child != null) {
Node next = curr.next;
Node child = flatten(curr.child);
curr.next = child;
child.prev = curr;
curr.child = null;
while (curr.next != null) curr = curr.next;
if (next != null) {
curr.next = next;
next.prev = curr;
}
}
curr = curr.next;
}
return head;
}
Explanation: When encountering child, flatten child list and insert between current and next. Continue traversing.
- Time Complexity: O(n)
- Space Complexity: O(depth)
431. Encode N-ary Tree to Binary Tree
Description: Encode N-ary tree to binary tree and decode back.
Java Solution:
// Encode: left child = first child, right child = next sibling
public TreeNode encode(Node root) {
if (root == null) return null;
TreeNode bRoot = new TreeNode(root.val);
if (!root.children.isEmpty()) {
bRoot.left = encode(root.children.get(0));
}
TreeNode curr = bRoot.left;
for (int i = 1; i < root.children.size(); i++) {
curr.right = encode(root.children.get(i));
curr = curr.right;
}
return bRoot;
}
public Node decode(TreeNode root) {
if (root == null) return null;
Node nRoot = new Node(root.val, new ArrayList<>());
TreeNode curr = root.left;
while (curr != null) {
nRoot.children.add(decode(curr));
curr = curr.right;
}
return nRoot;
}
Explanation: Use left-child right-sibling representation. Left points to first child, right points to next sibling.
- Time Complexity: O(n)
- Space Complexity: O(h)
432. All O’one Data Structure
Description: Design data structure for inc/dec key operations with O(1) getMaxKey/getMinKey.
Java Solution:
class AllOne {
class Node {
int count;
Set<String> keys = new LinkedHashSet<>();
Node prev, next;
Node(int c) { count = c; }
}
Map<String, Node> keyMap = new HashMap<>();
Node head = new Node(0), tail = new Node(0);
public AllOne() { head.next = tail; tail.prev = head; }
public void inc(String key) {
if (keyMap.containsKey(key)) {
Node node = keyMap.get(key);
node.keys.remove(key);
int newCount = node.count + 1;
Node next = node.next;
if (next == tail || next.count != newCount) {
next = insertAfter(node, newCount);
}
next.keys.add(key);
keyMap.put(key, next);
if (node.keys.isEmpty()) remove(node);
} else {
Node first = head.next;
if (first == tail || first.count != 1) {
first = insertAfter(head, 1);
}
first.keys.add(key);
keyMap.put(key, first);
}
}
public void dec(String key) {
Node node = keyMap.get(key);
node.keys.remove(key);
int newCount = node.count - 1;
if (newCount > 0) {
Node prev = node.prev;
if (prev == head || prev.count != newCount) {
prev = insertAfter(node.prev, newCount);
}
prev.keys.add(key);
keyMap.put(key, prev);
} else keyMap.remove(key);
if (node.keys.isEmpty()) remove(node);
}
public String getMaxKey() { return tail.prev == head ? "" : tail.prev.keys.iterator().next(); }
public String getMinKey() { return head.next == tail ? "" : head.next.keys.iterator().next(); }
private Node insertAfter(Node node, int count) {
Node newNode = new Node(count);
newNode.next = node.next;
newNode.prev = node;
node.next.prev = newNode;
node.next = newNode;
return newNode;
}
private void remove(Node node) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
}
Explanation: Doubly linked list of count nodes. Each node holds keys with that count. HashMap for O(1) key lookup.
- Time Complexity: O(1) all operations
- Space Complexity: O(n)
433. Minimum Genetic Mutation
Description: Find minimum mutations to transform start gene to end gene.
Java Solution:
public int minMutation(String start, String end, String[] bank) {
Set<String> bankSet = new HashSet<>(Arrays.asList(bank));
if (!bankSet.contains(end)) return -1;
Queue<String> queue = new LinkedList<>();
queue.offer(start);
Set<String> visited = new HashSet<>();
visited.add(start);
int mutations = 0;
char[] genes = {'A', 'C', 'G', 'T'};
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
String curr = queue.poll();
if (curr.equals(end)) return mutations;
char[] arr = curr.toCharArray();
for (int j = 0; j < 8; j++) {
char orig = arr[j];
for (char g : genes) {
arr[j] = g;
String next = new String(arr);
if (bankSet.contains(next) && !visited.contains(next)) {
visited.add(next);
queue.offer(next);
}
}
arr[j] = orig;
}
}
mutations++;
}
return -1;
}
Explanation: BFS from start. Try all single mutations. Only valid genes in bank. Return steps when end reached.
- Time Complexity: O(n × 8 × 4)
- Space Complexity: O(n)
434. Number of Segments in a String
Description: Count segments (contiguous non-space characters) in string.
Java Solution:
public int countSegments(String s) {
int count = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) != ' ' && (i == 0 || s.charAt(i - 1) == ' ')) {
count++;
}
}
return count;
}
Explanation: Count transitions from space to non-space. Check start of each segment.
- Time Complexity: O(n)
- Space Complexity: O(1)
435. Non-overlapping Intervals
Description: Find minimum intervals to remove for non-overlapping result.
Java Solution:
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[1] - b[1]);
int count = 0, end = Integer.MIN_VALUE;
for (int[] interval : intervals) {
if (interval[0] >= end) {
end = interval[1];
} else {
count++;
}
}
return count;
}
Explanation: Sort by end time. Greedily keep intervals ending earliest. Count overlapping intervals to remove.
- Time Complexity: O(n log n)
- Space Complexity: O(1)
436. Find Right Interval
Description: For each interval, find smallest start >= current end.
Java Solution:
public int[] findRightInterval(int[][] intervals) {
int n = intervals.length;
TreeMap<Integer, Integer> map = new TreeMap<>();
for (int i = 0; i < n; i++) map.put(intervals[i][0], i);
int[] result = new int[n];
for (int i = 0; i < n; i++) {
Integer key = map.ceilingKey(intervals[i][1]);
result[i] = key == null ? -1 : map.get(key);
}
return result;
}
Explanation: Store start points in TreeMap. For each interval, find ceiling of its end point.
- Time Complexity: O(n log n)
- Space Complexity: O(n)
437. Path Sum III
Description: Count paths in tree that sum to target (path can start/end anywhere).
Java Solution:
public int pathSum(TreeNode root, int targetSum) {
Map<Long, Integer> prefixSum = new HashMap<>();
prefixSum.put(0L, 1);
return dfs(root, 0, targetSum, prefixSum);
}
private int dfs(TreeNode node, long currSum, int target, Map<Long, Integer> prefixSum) {
if (node == null) return 0;
currSum += node.val;
int count = prefixSum.getOrDefault(currSum - target, 0);
prefixSum.merge(currSum, 1, Integer::sum);
count += dfs(node.left, currSum, target, prefixSum);
count += dfs(node.right, currSum, target, prefixSum);
prefixSum.merge(currSum, -1, Integer::sum);
return count;
}
Explanation: Use prefix sum technique. Track sums from root. Current path sum - target exists means valid path found.
- Time Complexity: O(n)
- Space Complexity: O(h)
438. Find All Anagrams in a String
Description: Find all start indices of p’s anagrams in s.
Java Solution:
public List<Integer> findAnagrams(String s, String p) {
List<Integer> result = new ArrayList<>();
if (s.length() < p.length()) return result;
int[] pCount = new int[26], sCount = new int[26];
for (char c : p.toCharArray()) pCount[c - 'a']++;
for (int i = 0; i < s.length(); i++) {
sCount[s.charAt(i) - 'a']++;
if (i >= p.length()) sCount[s.charAt(i - p.length()) - 'a']--;
if (Arrays.equals(pCount, sCount)) result.add(i - p.length() + 1);
}
return result;
}
Explanation: Sliding window of size p.length(). Compare character counts. Add index when counts match.
- Time Complexity: O(n)
- Space Complexity: O(1)
439. Ternary Expression Parser
Description: Parse ternary expression and return result.
Java Solution:
public String parseTernary(String expression) {
Deque<Character> stack = new ArrayDeque<>();
for (int i = expression.length() - 1; i >= 0; i--) {
char c = expression.charAt(i);
if (!stack.isEmpty() && stack.peek() == '?') {
stack.pop(); // remove '?'
char first = stack.pop();
stack.pop(); // remove ':'
char second = stack.pop();
stack.push(c == 'T' ? first : second);
} else {
stack.push(c);
}
}
return String.valueOf(stack.peek());
}
Explanation: Process right to left. When condition found with ? on stack, evaluate and push result.
- Time Complexity: O(n)
- Space Complexity: O(n)
440. K-th Smallest in Lexicographical Order
Description: Find k-th smallest number in lexicographical order from 1 to n.
Java Solution:
public int findKthNumber(int n, int k) {
int curr = 1;
k--;
while (k > 0) {
long count = countSteps(n, curr, curr + 1);
if (count <= k) {
k -= count;
curr++;
} else {
k--;
curr *= 10;
}
}
return curr;
}
private long countSteps(int n, long curr, long next) {
long steps = 0;
while (curr <= n) {
steps += Math.min(n + 1, next) - curr;
curr *= 10;
next *= 10;
}
return steps;
}
Explanation: Treat numbers as trie. Count numbers in subtree. Move right or down based on k.
- Time Complexity: O(log² n)
- Space Complexity: O(1)
441. Arranging Coins
Description: Find complete rows of staircase with n coins.
Java Solution:
public int arrangeCoins(int n) {
long left = 1, right = n;
while (left < right) {
long mid = left + (right - left + 1) / 2;
if (mid * (mid + 1) / 2 <= n) left = mid;
else right = mid - 1;
}
return (int) left;
}
Explanation: Binary search for k where k(k+1)/2 <= n. Use arithmetic sum formula.
- Time Complexity: O(log n)
- Space Complexity: O(1)
442. Find All Duplicates in an Array
Description: Find all elements appearing twice. Elements in range [1, n].
Java Solution:
public List<Integer> findDuplicates(int[] nums) {
List<Integer> result = new ArrayList<>();
for (int num : nums) {
int idx = Math.abs(num) - 1;
if (nums[idx] < 0) result.add(Math.abs(num));
else nums[idx] = -nums[idx];
}
return result;
}
Explanation: Use array indices as markers. Negate value at index. If already negative, number is duplicate.
- Time Complexity: O(n)
- Space Complexity: O(1)
443. String Compression
Description: Compress string in-place using count notation.
Java Solution:
public int compress(char[] chars) {
int write = 0, read = 0;
while (read < chars.length) {
char curr = chars[read];
int count = 0;
while (read < chars.length && chars[read] == curr) {
read++;
count++;
}
chars[write++] = curr;
if (count > 1) {
for (char c : String.valueOf(count).toCharArray()) {
chars[write++] = c;
}
}
}
return write;
}
Explanation: Two pointers. Count consecutive chars. Write char and count (if > 1). Return new length.
- Time Complexity: O(n)
- Space Complexity: O(1)
444. Sequence Reconstruction
Description: Check if original sequence can be uniquely reconstructed from subsequences.
Java Solution:
public boolean sequenceReconstruction(int[] org, List<List<Integer>> seqs) {
int n = org.length;
int[] indegree = new int[n + 1];
Map<Integer, Set<Integer>> graph = new HashMap<>();
Set<Integer> nodes = new HashSet<>();
for (List<Integer> seq : seqs) {
for (int i = 0; i < seq.size(); i++) {
nodes.add(seq.get(i));
if (seq.get(i) < 1 || seq.get(i) > n) return false;
if (i > 0) {
graph.computeIfAbsent(seq.get(i-1), k -> new HashSet<>());
if (graph.get(seq.get(i-1)).add(seq.get(i))) {
indegree[seq.get(i)]++;
}
}
}
}
if (nodes.size() != n) return false;
Queue<Integer> queue = new LinkedList<>();
for (int i = 1; i <= n; i++) {
if (indegree[i] == 0) queue.offer(i);
}
int idx = 0;
while (!queue.isEmpty()) {
if (queue.size() > 1) return false;
int curr = queue.poll();
if (idx >= n || curr != org[idx++]) return false;
for (int next : graph.getOrDefault(curr, new HashSet<>())) {
if (--indegree[next] == 0) queue.offer(next);
}
}
return idx == n;
}
Explanation: Build graph from sequences. Topological sort must be unique (queue size always 1) and match original.
- Time Complexity: O(n + e)
- Space Complexity: O(n + e)
445. Add Two Numbers II
Description: Add two numbers represented by linked lists (most significant digit first).
Java Solution:
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
Deque<Integer> s1 = new ArrayDeque<>(), s2 = new ArrayDeque<>();
while (l1 != null) { s1.push(l1.val); l1 = l1.next; }
while (l2 != null) { s2.push(l2.val); l2 = l2.next; }
ListNode head = null;
int carry = 0;
while (!s1.isEmpty() || !s2.isEmpty() || carry > 0) {
int sum = carry;
if (!s1.isEmpty()) sum += s1.pop();
if (!s2.isEmpty()) sum += s2.pop();
ListNode node = new ListNode(sum % 10);
node.next = head;
head = node;
carry = sum / 10;
}
return head;
}
Explanation: Use stacks to reverse order. Add from least significant. Build result list from head.
- Time Complexity: O(n + m)
- Space Complexity: O(n + m)
446. Arithmetic Slices II - Subsequence
Description: Count arithmetic subsequences of length >= 3.
Java Solution:
public int numberOfArithmeticSlices(int[] nums) {
int n = nums.length, count = 0;
Map<Long, Integer>[] dp = new HashMap[n];
for (int i = 0; i < n; i++) dp[i] = new HashMap<>();
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
long diff = (long) nums[i] - nums[j];
int prev = dp[j].getOrDefault(diff, 0);
count += prev;
dp[i].merge(diff, prev + 1, Integer::sum);
}
}
return count;
}
Explanation: dp[i][diff] = count of subsequences ending at i with difference diff. Add prev counts (length >= 3).
- Time Complexity: O(n²)
- Space Complexity: O(n²)
447. Number of Boomerangs
Description: Count tuples (i, j, k) where distance(i,j) = distance(i,k).
Java Solution:
public int numberOfBoomerangs(int[][] points) {
int count = 0;
for (int[] p1 : points) {
Map<Integer, Integer> distCount = new HashMap<>();
for (int[] p2 : points) {
int dist = (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]);
distCount.merge(dist, 1, Integer::sum);
}
for (int c : distCount.values()) {
count += c * (c - 1);
}
}
return count;
}
Explanation: For each point, count points at each distance. For n points at same distance, n*(n-1) boomerangs.
- Time Complexity: O(n²)
- Space Complexity: O(n)
448. Find All Numbers Disappeared in an Array
Description: Find all numbers in [1, n] missing from array.
Java Solution:
public List<Integer> findDisappearedNumbers(int[] nums) {
for (int num : nums) {
int idx = Math.abs(num) - 1;
if (nums[idx] > 0) nums[idx] = -nums[idx];
}
List<Integer> result = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
if (nums[i] > 0) result.add(i + 1);
}
return result;
}
Explanation: Mark indices as negative. Positive indices indicate missing numbers.
- Time Complexity: O(n)
- Space Complexity: O(1)
449. Serialize and Deserialize BST
Description: Serialize and deserialize BST optimally.
Java Solution:
public String serialize(TreeNode root) {
if (root == null) return "";
StringBuilder sb = new StringBuilder();
serialize(root, sb);
return sb.toString().trim();
}
private void serialize(TreeNode node, StringBuilder sb) {
if (node == null) return;
sb.append(node.val).append(" ");
serialize(node.left, sb);
serialize(node.right, sb);
}
public TreeNode deserialize(String data) {
if (data.isEmpty()) return null;
Queue<Integer> queue = new LinkedList<>();
for (String s : data.split(" ")) queue.offer(Integer.parseInt(s));
return deserialize(queue, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
private TreeNode deserialize(Queue<Integer> queue, int min, int max) {
if (queue.isEmpty() || queue.peek() < min || queue.peek() > max) return null;
TreeNode node = new TreeNode(queue.poll());
node.left = deserialize(queue, min, node.val);
node.right = deserialize(queue, node.val, max);
return node;
}
Explanation: Preorder traversal for serialize. Deserialize using BST property to determine left/right placement.
- Time Complexity: O(n)
- Space Complexity: O(n)
450. Delete Node in a BST
Description: Delete node with given key from BST.
Java Solution:
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) return null;
if (key < root.val) {
root.left = deleteNode(root.left, key);
} else if (key > root.val) {
root.right = deleteNode(root.right, key);
} else {
if (root.left == null) return root.right;
if (root.right == null) return root.left;
TreeNode successor = root.right;
while (successor.left != null) successor = successor.left;
root.val = successor.val;
root.right = deleteNode(root.right, successor.val);
}
return root;
}
Explanation: Find node. If leaf, remove. If one child, replace with child. If two children, replace with inorder successor.
- Time Complexity: O(h)
- Space Complexity: O(h)
451. Sort Characters By Frequency
Description: Sort characters by decreasing frequency.
Java Solution:
public String frequencySort(String s) {
Map<Character, Integer> freq = new HashMap<>();
for (char c : s.toCharArray()) freq.merge(c, 1, Integer::sum);
PriorityQueue<Character> pq = new PriorityQueue<>((a, b) -> freq.get(b) - freq.get(a));
pq.addAll(freq.keySet());
StringBuilder sb = new StringBuilder();
while (!pq.isEmpty()) {
char c = pq.poll();
for (int i = 0; i < freq.get(c); i++) sb.append(c);
}
return sb.toString();
}
Explanation: Count frequencies, use max-heap sorted by frequency, build result string.
- Time Complexity: O(n log k)
- Space Complexity: O(n)
452. Minimum Number of Arrows to Burst Balloons
Description: Find minimum arrows to burst all balloons.
Java Solution:
public int findMinArrowShots(int[][] points) {
Arrays.sort(points, (a, b) -> Integer.compare(a[1], b[1]));
int arrows = 1, end = points[0][1];
for (int i = 1; i < points.length; i++) {
if (points[i][0] > end) {
arrows++;
end = points[i][1];
}
}
return arrows;
}
Explanation: Sort by end point. Shoot at end of current balloon. Skip overlapping balloons. Count shots needed.
- Time Complexity: O(n log n)
- Space Complexity: O(1)
453. Minimum Moves to Equal Array Elements
Description: Find minimum moves to make all elements equal (each move increments n-1 elements).
Java Solution:
public int minMoves(int[] nums) {
int min = Arrays.stream(nums).min().getAsInt();
int sum = Arrays.stream(nums).sum();
return sum - min * nums.length;
}
Explanation: Incrementing n-1 elements equals decrementing 1 element. Count steps to reduce all to minimum.
- Time Complexity: O(n)
- Space Complexity: O(1)
454. 4Sum II
Description: Count tuples where A[i]+B[j]+C[k]+D[l]=0.
Java Solution:
public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
Map<Integer, Integer> map = new HashMap<>();
for (int a : A) {
for (int b : B) {
map.merge(a + b, 1, Integer::sum);
}
}
int count = 0;
for (int c : C) {
for (int d : D) {
count += map.getOrDefault(-(c + d), 0);
}
}
return count;
}
Explanation: Store all A+B sums. For each C+D, count matching -(C+D) in map.
- Time Complexity: O(n²)
- Space Complexity: O(n²)
455. Assign Cookies
Description: Maximize content children with cookies.
Java Solution:
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int i = 0, j = 0;
while (i < g.length && j < s.length) {
if (s[j] >= g[i]) i++;
j++;
}
return i;
}
Explanation: Sort both. Greedily assign smallest sufficient cookie to least greedy child.
- Time Complexity: O(n log n)
- Space Complexity: O(1)
456. 132 Pattern
Description: Find 132 pattern in array.
Java Solution:
public boolean find132pattern(int[] nums) {
Deque<Integer> stack = new ArrayDeque<>();
int third = Integer.MIN_VALUE;
for (int i = nums.length - 1; i >= 0; i--) {
if (nums[i] < third) return true;
while (!stack.isEmpty() && nums[i] > stack.peek()) {
third = stack.pop();
}
stack.push(nums[i]);
}
return false;
}
Explanation: Scan right to left. Stack maintains candidates for “3”. Track max “2” (third). If current < third, found “1”.
- Time Complexity: O(n)
- Space Complexity: O(n)
457. Circular Array Loop
Description: Detect cycle with consistent direction in circular array.
Java Solution:
public boolean circularArrayLoop(int[] nums) {
int n = nums.length;
for (int i = 0; i < n; i++) {
if (nums[i] == 0) continue;
int slow = i, fast = i;
while (nums[fast] * nums[i] > 0 && nums[next(fast, nums)] * nums[i] > 0) {
slow = next(slow, nums);
fast = next(next(fast, nums), nums);
if (slow == fast) {
if (slow == next(slow, nums)) break;
return true;
}
}
int j = i;
while (nums[j] * nums[i] > 0) {
int tmp = next(j, nums);
nums[j] = 0;
j = tmp;
}
}
return false;
}
private int next(int i, int[] nums) {
int n = nums.length;
return ((i + nums[i]) % n + n) % n;
}
Explanation: Floyd’s cycle detection. Check direction consistency. Mark visited to avoid revisiting.
- Time Complexity: O(n)
- Space Complexity: O(1)
458. Poor Pigs
Description: Find minimum pigs to identify poisonous bucket.
Java Solution:
public int poorPigs(int buckets, int minutesToDie, int minutesToTest) {
int rounds = minutesToTest / minutesToDie + 1;
int pigs = 0;
while (Math.pow(rounds, pigs) < buckets) pigs++;
return pigs;
}
Explanation: Each pig can represent (rounds) states. Need pigs where rounds^pigs >= buckets.
- Time Complexity: O(log buckets)
- Space Complexity: O(1)
459. Repeated Substring Pattern
Description: Check if string is made of repeated substring.
Java Solution:
public boolean repeatedSubstringPattern(String s) {
return (s + s).substring(1, 2 * s.length() - 1).contains(s);
}
Explanation: If s has repeated pattern, it appears in (s+s) excluding first and last chars.
- Time Complexity: O(n²)
- Space Complexity: O(n)
460. LFU Cache
Description: Design LFU cache with O(1) operations.
Java Solution:
class LFUCache {
private Map<Integer, Integer> values;
private Map<Integer, Integer> counts;
private Map<Integer, LinkedHashSet<Integer>> lists;
private int cap, min;
public LFUCache(int capacity) {
cap = capacity; min = 0;
values = new HashMap<>();
counts = new HashMap<>();
lists = new HashMap<>();
}
public int get(int key) {
if (!values.containsKey(key)) return -1;
int count = counts.get(key);
counts.put(key, count + 1);
lists.get(count).remove(key);
if (count == min && lists.get(count).isEmpty()) min++;
lists.computeIfAbsent(count + 1, k -> new LinkedHashSet<>()).add(key);
return values.get(key);
}
public void put(int key, int value) {
if (cap <= 0) return;
if (values.containsKey(key)) { values.put(key, value); get(key); return; }
if (values.size() >= cap) {
int evict = lists.get(min).iterator().next();
lists.get(min).remove(evict);
values.remove(evict);
counts.remove(evict);
}
values.put(key, value);
counts.put(key, 1);
min = 1;
lists.computeIfAbsent(1, k -> new LinkedHashSet<>()).add(key);
}
}
Explanation: Three maps: values, counts, and frequency lists. LinkedHashSet maintains insertion order for LRU within same frequency.
- Time Complexity: O(1) all operations
- Space Complexity: O(capacity)
461. Hamming Distance
Description: Count differing bits between two integers.
Java Solution:
public int hammingDistance(int x, int y) {
return Integer.bitCount(x ^ y);
}
Explanation: XOR gives 1s where bits differ. Count those 1s.
- Time Complexity: O(1)
- Space Complexity: O(1)
462. Minimum Moves to Equal Array Elements II
Description: Find minimum moves to make all equal (move = change by 1).
Java Solution:
public int minMoves2(int[] nums) {
Arrays.sort(nums);
int median = nums[nums.length / 2];
int moves = 0;
for (int num : nums) moves += Math.abs(num - median);
return moves;
}
Explanation: Median minimizes sum of absolute deviations. Sum distances to median.
- Time Complexity: O(n log n)
- Space Complexity: O(1)
463. Island Perimeter
Description: Calculate perimeter of island in grid.
Java Solution:
public int islandPerimeter(int[][] grid) {
int perimeter = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
perimeter += 4;
if (i > 0 && grid[i-1][j] == 1) perimeter -= 2;
if (j > 0 && grid[i][j-1] == 1) perimeter -= 2;
}
}
}
return perimeter;
}
Explanation: Each land cell adds 4. Subtract 2 for each adjacent land cell (shared edge).
- Time Complexity: O(m×n)
- Space Complexity: O(1)
464. Can I Win
Description: Determine if first player can guarantee win.
Java Solution:
private Map<Integer, Boolean> memo = new HashMap<>();
public boolean canIWin(int maxChoosableInteger, int desiredTotal) {
if (maxChoosableInteger * (maxChoosableInteger + 1) / 2 < desiredTotal) return false;
return canWin(maxChoosableInteger, desiredTotal, 0);
}
private boolean canWin(int max, int total, int used) {
if (memo.containsKey(used)) return memo.get(used);
for (int i = 1; i <= max; i++) {
int mask = 1 << i;
if ((used & mask) == 0) {
if (i >= total || !canWin(max, total - i, used | mask)) {
memo.put(used, true);
return true;
}
}
}
memo.put(used, false);
return false;
}
Explanation: Memoized game theory. Win if can reach target or opponent can’t win after our move.
- Time Complexity: O(2^n)
- Space Complexity: O(2^n)
465. Optimal Account Balancing
Description: Minimum transactions to settle debts.
Java Solution:
public int minTransfers(int[][] transactions) {
Map<Integer, Integer> balance = new HashMap<>();
for (int[] t : transactions) {
balance.merge(t[0], -t[2], Integer::sum);
balance.merge(t[1], t[2], Integer::sum);
}
List<Integer> debts = new ArrayList<>();
for (int b : balance.values()) if (b != 0) debts.add(b);
return settle(debts, 0);
}
private int settle(List<Integer> debts, int start) {
while (start < debts.size() && debts.get(start) == 0) start++;
if (start == debts.size()) return 0;
int result = Integer.MAX_VALUE;
for (int i = start + 1; i < debts.size(); i++) {
if (debts.get(start) * debts.get(i) < 0) {
debts.set(i, debts.get(i) + debts.get(start));
result = Math.min(result, 1 + settle(debts, start + 1));
debts.set(i, debts.get(i) - debts.get(start));
}
}
return result;
}
Explanation: Calculate net balance per person. Backtrack to find minimum transactions settling all debts.
- Time Complexity: O(n!)
- Space Complexity: O(n)
466. Count The Repetitions
Description: Find maximum M where [s2, M] can be obtained from [s1, n1].
Java Solution:
public int getMaxRepetitions(String s1, int n1, String s2, int n2) {
int[] repeatCount = new int[n1 + 1];
int[] nextIndex = new int[n1 + 1];
int j = 0, cnt = 0;
for (int k = 1; k <= n1; k++) {
for (int i = 0; i < s1.length(); i++) {
if (s1.charAt(i) == s2.charAt(j)) {
j++;
if (j == s2.length()) { j = 0; cnt++; }
}
}
repeatCount[k] = cnt;
nextIndex[k] = j;
for (int start = 0; start < k; start++) {
if (nextIndex[start] == j) {
int prefixCount = repeatCount[start];
int patternCount = (repeatCount[k] - repeatCount[start]) * ((n1 - start) / (k - start));
int suffixCount = repeatCount[start + (n1 - start) % (k - start)] - repeatCount[start];
return (prefixCount + patternCount + suffixCount) / n2;
}
}
}
return repeatCount[n1] / n2;
}
Explanation: Find cycle in s2 index positions. Use cycle to compute total s2 occurrences efficiently.
- Time Complexity: O(n1 × len(s1))
- Space Complexity: O(n1)
467. Unique Substrings in Wraparound String
Description: Count unique substrings that are in infinite wraparound of “abc…z”.
Java Solution:
public int findSubstringInWraproundString(String p) {
int[] maxLen = new int[26];
int len = 0;
for (int i = 0; i < p.length(); i++) {
if (i > 0 && (p.charAt(i) - p.charAt(i-1) + 26) % 26 == 1) len++;
else len = 1;
maxLen[p.charAt(i) - 'a'] = Math.max(maxLen[p.charAt(i) - 'a'], len);
}
int total = 0;
for (int m : maxLen) total += m;
return total;
}
Explanation: For each ending char, track max consecutive length. Sum gives unique substrings count.
- Time Complexity: O(n)
- Space Complexity: O(1)
468. Validate IP Address
Description: Classify string as IPv4, IPv6, or Neither.
Java Solution:
public String validIPAddress(String IP) {
if (isIPv4(IP)) return "IPv4";
if (isIPv6(IP)) return "IPv6";
return "Neither";
}
private boolean isIPv4(String ip) {
if (ip.endsWith(".")) return false;
String[] parts = ip.split("\\.", -1);
if (parts.length != 4) return false;
for (String part : parts) {
if (part.isEmpty() || part.length() > 3) return false;
if (part.length() > 1 && part.charAt(0) == '0') return false;
try {
int num = Integer.parseInt(part);
if (num < 0 || num > 255) return false;
} catch (NumberFormatException e) { return false; }
}
return true;
}
private boolean isIPv6(String ip) {
if (ip.endsWith(":")) return false;
String[] parts = ip.split(":", -1);
if (parts.length != 8) return false;
for (String part : parts) {
if (part.isEmpty() || part.length() > 4) return false;
for (char c : part.toCharArray()) {
if (!Character.isDigit(c) && (c < 'a' || c > 'f') && (c < 'A' || c > 'F')) return false;
}
}
return true;
}
Explanation: Check format rules for IPv4 (4 parts, 0-255, no leading zeros) and IPv6 (8 parts, hex, max 4 chars).
- Time Complexity: O(n)
- Space Complexity: O(1)
469. Convex Polygon
Description: Check if polygon is convex.
Java Solution:
public boolean isConvex(List<List<Integer>> points) {
int n = points.size();
long sign = 0;
for (int i = 0; i < n; i++) {
long cross = crossProduct(points.get(i), points.get((i+1)%n), points.get((i+2)%n));
if (cross != 0) {
if (sign == 0) sign = cross > 0 ? 1 : -1;
else if ((cross > 0 && sign < 0) || (cross < 0 && sign > 0)) return false;
}
}
return true;
}
private long crossProduct(List<Integer> a, List<Integer> b, List<Integer> c) {
return (long)(b.get(0) - a.get(0)) * (c.get(1) - b.get(1)) -
(long)(b.get(1) - a.get(1)) * (c.get(0) - b.get(0));
}
Explanation: Convex if all cross products have same sign (all turns in same direction).
- Time Complexity: O(n)
- Space Complexity: O(1)
470. Implement Rand10() Using Rand7()
Description: Generate uniform random [1,10] using rand7().
Java Solution:
public int rand10() {
int result;
do {
result = (rand7() - 1) * 7 + rand7();
} while (result > 40);
return result % 10 + 1;
}
Explanation: Generate [1,49] uniformly. Reject [41,49]. Map [1,40] to [1,10].
- Time Complexity: O(1) expected
- Space Complexity: O(1)
471. Encode String with Shortest Length
Description: Encode string with shortest length using k[encoded_string] format.
Java Solution:
public String encode(String s) {
int n = s.length();
String[][] dp = new String[n][n];
for (int len = 1; len <= n; len++) {
for (int i = 0; i + len - 1 < n; i++) {
int j = i + len - 1;
String substr = s.substring(i, j + 1);
dp[i][j] = substr;
if (len > 4) {
for (int k = i; k < j; k++) {
if (dp[i][k].length() + dp[k+1][j].length() < dp[i][j].length()) {
dp[i][j] = dp[i][k] + dp[k+1][j];
}
}
String pattern = findPattern(substr);
if (pattern != null) {
String encoded = (substr.length() / pattern.length()) + "[" + dp[i][i + pattern.length() - 1] + "]";
if (encoded.length() < dp[i][j].length()) dp[i][j] = encoded;
}
}
}
}
return dp[0][n-1];
}
private String findPattern(String s) {
String doubled = s + s;
int idx = doubled.indexOf(s, 1);
return idx < s.length() ? s.substring(0, idx) : null;
}
Explanation: DP on substrings. Try splitting and encoding repeated patterns. Use trick: s+s contains s at position < n iff s has repeated pattern.
- Time Complexity: O(n³)
- Space Complexity: O(n²)
472. Concatenated Words
Description: Find words composed of other words in list.
Java Solution:
public List<String> findAllConcatenatedWordsInADict(String[] words) {
Set<String> dict = new HashSet<>(Arrays.asList(words));
List<String> result = new ArrayList<>();
for (String word : words) {
if (canForm(word, dict)) result.add(word);
}
return result;
}
private boolean canForm(String word, Set<String> dict) {
if (word.isEmpty()) return false;
boolean[] dp = new boolean[word.length() + 1];
dp[0] = true;
for (int i = 1; i <= word.length(); i++) {
for (int j = (i == word.length() ? 1 : 0); j < i; j++) {
if (dp[j] && dict.contains(word.substring(j, i))) {
dp[i] = true;
break;
}
}
}
return dp[word.length()];
}
Explanation: For each word, check if it can be formed by other words using DP (word break). Ensure at least 2 words used.
- Time Complexity: O(n × m²)
- Space Complexity: O(n × m)
473. Matchsticks to Square
Description: Check if matchsticks can form square.
Java Solution:
public boolean makesquare(int[] matchsticks) {
int sum = Arrays.stream(matchsticks).sum();
if (sum % 4 != 0) return false;
int side = sum / 4;
Arrays.sort(matchsticks);
reverse(matchsticks);
return dfs(matchsticks, new int[4], 0, side);
}
private boolean dfs(int[] nums, int[] sides, int idx, int target) {
if (idx == nums.length) return true;
for (int i = 0; i < 4; i++) {
if (sides[i] + nums[idx] <= target) {
sides[i] += nums[idx];
if (dfs(nums, sides, idx + 1, target)) return true;
sides[i] -= nums[idx];
}
if (sides[i] == 0) break;
}
return false;
}
private void reverse(int[] arr) {
int l = 0, r = arr.length - 1;
while (l < r) { int t = arr[l]; arr[l++] = arr[r]; arr[r--] = t; }
}
Explanation: Backtracking to assign each matchstick to one of 4 sides. Sort descending for early pruning.
- Time Complexity: O(4^n)
- Space Complexity: O(n)
474. Ones and Zeroes
Description: Max strings from array using at most m 0s and n 1s.
Java Solution:
public int findMaxForm(String[] strs, int m, int n) {
int[][] dp = new int[m + 1][n + 1];
for (String s : strs) {
int zeros = (int) s.chars().filter(c -> c == '0').count();
int ones = s.length() - zeros;
for (int i = m; i >= zeros; i--) {
for (int j = n; j >= ones; j--) {
dp[i][j] = Math.max(dp[i][j], dp[i - zeros][j - ones] + 1);
}
}
}
return dp[m][n];
}
Explanation: 2D knapsack: dp[i][j] = max strings using i 0s and j 1s. Iterate backwards to avoid reuse.
- Time Complexity: O(l × m × n)
- Space Complexity: O(m × n)
475. Heaters
Description: Find minimum radius for heaters to cover all houses.
Java Solution:
public int findRadius(int[] houses, int[] heaters) {
Arrays.sort(houses);
Arrays.sort(heaters);
int radius = 0, i = 0;
for (int house : houses) {
while (i < heaters.length - 1 &&
Math.abs(heaters[i + 1] - house) <= Math.abs(heaters[i] - house)) {
i++;
}
radius = Math.max(radius, Math.abs(heaters[i] - house));
}
return radius;
}
Explanation: For each house, find closest heater. Maximum distance needed is the answer.
- Time Complexity: O(n log n + m log m)
- Space Complexity: O(1)
476. Number Complement
Description: Find complement of an integer (flip all bits).
Java Solution:
public int findComplement(int num) {
int mask = (Integer.highestOneBit(num) << 1) - 1;
return num ^ mask;
}
Explanation: Create mask of all 1s up to highest bit. XOR flips all bits.
- Time Complexity: O(1)
- Space Complexity: O(1)
477. Total Hamming Distance
Description: Sum of Hamming distances between all pairs of numbers.
Java Solution:
public int totalHammingDistance(int[] nums) {
int total = 0, n = nums.length;
for (int i = 0; i < 32; i++) {
int ones = 0;
for (int num : nums) {
ones += (num >> i) & 1;
}
total += ones * (n - ones);
}
return total;
}
Explanation: For each bit position, count 1s and 0s. Pairs with different bits = ones × zeros.
- Time Complexity: O(32n)
- Space Complexity: O(1)
478. Generate Random Point in a Circle
Description: Generate uniformly random point inside circle.
Java Solution:
class Solution {
double radius, x_center, y_center;
Random rand = new Random();
public Solution(double radius, double x_center, double y_center) {
this.radius = radius;
this.x_center = x_center;
this.y_center = y_center;
}
public double[] randPoint() {
double r = Math.sqrt(rand.nextDouble()) * radius;
double theta = rand.nextDouble() * 2 * Math.PI;
return new double[]{x_center + r * Math.cos(theta), y_center + r * Math.sin(theta)};
}
}
Explanation: Use sqrt for radius to ensure uniform distribution. Random angle for direction.
- Time Complexity: O(1)
- Space Complexity: O(1)
479. Largest Palindrome Product
Description: Find largest palindrome from product of two n-digit numbers mod 1337.
Java Solution:
public int largestPalindrome(int n) {
if (n == 1) return 9;
long upper = (long) Math.pow(10, n) - 1;
long lower = upper / 10;
for (long i = upper; i > lower; i--) {
long palindrome = createPalindrome(i);
for (long j = upper; j * j >= palindrome; j--) {
if (palindrome % j == 0 && palindrome / j <= upper) {
return (int) (palindrome % 1337);
}
}
}
return -1;
}
private long createPalindrome(long num) {
String s = num + new StringBuilder(String.valueOf(num)).reverse().toString();
return Long.parseLong(s);
}
Explanation: Generate palindromes from largest. Check if divisible by n-digit number with n-digit quotient.
- Time Complexity: O(10^n × sqrt(10^2n))
- Space Complexity: O(n)
480. Sliding Window Median
Description: Find median of each sliding window of size k.
Java Solution:
public double[] medianSlidingWindow(int[] nums, int k) {
TreeMap<Integer, Integer> small = new TreeMap<>(Collections.reverseOrder());
TreeMap<Integer, Integer> large = new TreeMap<>();
int smallSize = 0, largeSize = 0;
double[] result = new double[nums.length - k + 1];
for (int i = 0; i < nums.length; i++) {
if (smallSize == 0 || nums[i] <= small.firstKey()) {
small.merge(nums[i], 1, Integer::sum);
smallSize++;
} else {
large.merge(nums[i], 1, Integer::sum);
largeSize++;
}
// Balance
while (smallSize > largeSize + 1) {
move(small, large);
smallSize--; largeSize++;
}
while (largeSize > smallSize) {
move(large, small);
largeSize--; smallSize++;
}
if (i >= k - 1) {
if (k % 2 == 1) result[i - k + 1] = small.firstKey();
else result[i - k + 1] = ((double) small.firstKey() + large.firstKey()) / 2;
int toRemove = nums[i - k + 1];
if (toRemove <= small.firstKey()) {
remove(small, toRemove); smallSize--;
} else {
remove(large, toRemove); largeSize--;
}
}
}
return result;
}
private void move(TreeMap<Integer, Integer> from, TreeMap<Integer, Integer> to) {
int val = from.firstKey();
remove(from, val);
to.merge(val, 1, Integer::sum);
}
private void remove(TreeMap<Integer, Integer> map, int val) {
if (map.merge(val, -1, Integer::sum) == 0) map.remove(val);
}
Explanation: Two TreeMaps: small (max-heap) and large (min-heap). Balance to keep median accessible.
- Time Complexity: O(n log k)
- Space Complexity: O(k)
481. Magical String
Description: Count 1s in first n characters of magical string.
Java Solution:
public int magicalString(int n) {
if (n <= 0) return 0;
if (n <= 3) return 1;
int[] s = new int[n + 1];
s[0] = 1; s[1] = 2; s[2] = 2;
int head = 2, tail = 3, num = 1, count = 1;
while (tail < n) {
for (int i = 0; i < s[head] && tail < n; i++) {
s[tail++] = num;
if (num == 1) count++;
}
num = 3 - num;
head++;
}
return count;
}
Explanation: Generate string using self-describing property. Count 1s while generating.
- Time Complexity: O(n)
- Space Complexity: O(n)
482. License Key Formatting
Description: Reformat license key with groups of K characters.
Java Solution:
public String licenseKeyFormatting(String s, int k) {
StringBuilder sb = new StringBuilder();
for (int i = s.length() - 1; i >= 0; i--) {
if (s.charAt(i) != '-') {
if (sb.length() % (k + 1) == k) sb.append('-');
sb.append(Character.toUpperCase(s.charAt(i)));
}
}
return sb.reverse().toString();
}
Explanation: Build from right. Insert dash every K characters. Reverse result.
- Time Complexity: O(n)
- Space Complexity: O(n)
483. Smallest Good Base
Description: Find smallest base where n is all 1s.
Java Solution:
public String smallestGoodBase(String n) {
long num = Long.parseLong(n);
for (int m = 63; m >= 2; m--) {
long k = (long) Math.pow(num, 1.0 / m);
if (k > 1) {
long sum = 0, mul = 1;
for (int i = 0; i <= m; i++) {
sum += mul;
mul *= k;
}
if (sum == num) return String.valueOf(k);
}
}
return String.valueOf(num - 1);
}
Explanation: Try different number of 1s (m+1). Calculate base k. Verify sum equals n.
- Time Complexity: O(log² n)
- Space Complexity: O(1)
484. Find Permutation
Description: Find lexicographically smallest permutation matching DI pattern.
Java Solution:
public int[] findPermutation(String s) {
int n = s.length();
int[] result = new int[n + 1];
Deque<Integer> stack = new ArrayDeque<>();
int j = 0;
for (int i = 1; i <= n + 1; i++) {
stack.push(i);
if (i == n + 1 || s.charAt(i - 1) == 'I') {
while (!stack.isEmpty()) result[j++] = stack.pop();
}
}
return result;
}
Explanation: Push to stack. On ‘I’ or end, pop all to result. Creates increasing after I, decreasing for D.
- Time Complexity: O(n)
- Space Complexity: O(n)
485. Max Consecutive Ones
Description: Find maximum consecutive 1s in binary array.
Java Solution:
public int findMaxConsecutiveOnes(int[] nums) {
int max = 0, count = 0;
for (int num : nums) {
if (num == 1) max = Math.max(max, ++count);
else count = 0;
}
return max;
}
Explanation: Count consecutive 1s. Reset on 0. Track maximum.
- Time Complexity: O(n)
- Space Complexity: O(1)
486. Predict the Winner
Description: Determine if player 1 can win picking from array ends.
Java Solution:
public boolean predictTheWinner(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
for (int i = n - 1; i >= 0; i--) {
for (int j = i; j < n; j++) {
if (i == j) dp[j] = nums[i];
else dp[j] = Math.max(nums[i] - dp[j], nums[j] - dp[j - 1]);
}
}
return dp[n - 1] >= 0;
}
Explanation: dp[j] = max score difference for subarray. Player 1 wins if difference >= 0.
- Time Complexity: O(n²)
- Space Complexity: O(n)
487. Max Consecutive Ones II
Description: Find max consecutive 1s if you can flip at most one 0.
Java Solution:
public int findMaxConsecutiveOnes(int[] nums) {
int left = 0, right = 0, zeros = 0, max = 0;
while (right < nums.length) {
if (nums[right++] == 0) zeros++;
while (zeros > 1) {
if (nums[left++] == 0) zeros--;
}
max = Math.max(max, right - left);
}
return max;
}
Explanation: Sliding window allowing at most one 0. Shrink when more than one 0.
- Time Complexity: O(n)
- Space Complexity: O(1)
488. Zuma Game
Description: Find minimum balls to insert to clear board.
Java Solution:
public int findMinStep(String board, String hand) {
Map<String, Integer> memo = new HashMap<>();
int result = dfs(board, hand, memo);
return result == Integer.MAX_VALUE ? -1 : result;
}
private int dfs(String board, String hand, Map<String, Integer> memo) {
if (board.isEmpty()) return 0;
if (hand.isEmpty()) return Integer.MAX_VALUE;
String key = board + "#" + hand;
if (memo.containsKey(key)) return memo.get(key);
int result = Integer.MAX_VALUE;
for (int i = 0; i < hand.length(); i++) {
char c = hand.charAt(i);
String newHand = hand.substring(0, i) + hand.substring(i + 1);
for (int j = 0; j <= board.length(); j++) {
if (j > 0 && board.charAt(j - 1) == c) continue;
if (j < board.length() && board.charAt(j) == c) {
String newBoard = remove(board.substring(0, j) + c + board.substring(j));
int sub = dfs(newBoard, newHand, memo);
if (sub != Integer.MAX_VALUE) result = Math.min(result, sub + 1);
}
}
}
memo.put(key, result);
return result;
}
private String remove(String s) {
int i = 0;
while (i < s.length()) {
int j = i;
while (j < s.length() && s.charAt(j) == s.charAt(i)) j++;
if (j - i >= 3) {
s = s.substring(0, i) + s.substring(j);
i = 0;
} else i = j;
}
return s;
}
Explanation: DFS with memoization. Try inserting each ball at positions matching color. Remove 3+ consecutive.
- Time Complexity: O(m! × n × m)
- Space Complexity: O(m! × n)
489. Robot Room Cleaner
Description: Clean entire room using robot API.
Java Solution:
public void cleanRoom(Robot robot) {
Set<String> visited = new HashSet<>();
int[][] dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
dfs(robot, 0, 0, 0, dirs, visited);
}
private void dfs(Robot robot, int x, int y, int d, int[][] dirs, Set<String> visited) {
String key = x + "," + y;
if (visited.contains(key)) return;
visited.add(key);
robot.clean();
for (int i = 0; i < 4; i++) {
if (robot.move()) {
dfs(robot, x + dirs[d][0], y + dirs[d][1], d, dirs, visited);
robot.turnRight();
robot.turnRight();
robot.move();
robot.turnRight();
robot.turnRight();
}
robot.turnRight();
d = (d + 1) % 4;
}
}
Explanation: DFS with backtracking. Track visited cells. Turn right after each direction attempt.
- Time Complexity: O(n - m)
- Space Complexity: O(n - m)
490. The Maze
Description: Determine if ball can reach destination in maze.
Java Solution:
public boolean hasPath(int[][] maze, int[] start, int[] destination) {
boolean[][] visited = new boolean[maze.length][maze[0].length];
return dfs(maze, start[0], start[1], destination, visited);
}
private boolean dfs(int[][] maze, int r, int c, int[] dest, boolean[][] visited) {
if (r == dest[0] && c == dest[1]) return true;
if (visited[r][c]) return false;
visited[r][c] = true;
int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
for (int[] d : dirs) {
int nr = r, nc = c;
while (nr + d[0] >= 0 && nr + d[0] < maze.length &&
nc + d[1] >= 0 && nc + d[1] < maze[0].length &&
maze[nr + d[0]][nc + d[1]] == 0) {
nr += d[0];
nc += d[1];
}
if (dfs(maze, nr, nc, dest, visited)) return true;
}
return false;
}
Explanation: DFS where ball rolls until hitting wall. Check if any path reaches destination.
- Time Complexity: O(mn)
- Space Complexity: O(mn)
491. Non-decreasing Subsequences
Description: Find all non-decreasing subsequences of length >= 2.
Java Solution:
public List<List<Integer>> findSubsequences(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
backtrack(nums, 0, new ArrayList<>(), result);
return result;
}
private void backtrack(int[] nums, int start, List<Integer> path, List<List<Integer>> result) {
if (path.size() >= 2) result.add(new ArrayList<>(path));
Set<Integer> used = new HashSet<>();
for (int i = start; i < nums.length; i++) {
if (used.contains(nums[i])) continue;
if (path.isEmpty() || nums[i] >= path.get(path.size() - 1)) {
used.add(nums[i]);
path.add(nums[i]);
backtrack(nums, i + 1, path, result);
path.remove(path.size() - 1);
}
}
}
Explanation: Backtrack. Use set to avoid duplicates at same level. Only add if >= last element.
- Time Complexity: O(2^n × n)
- Space Complexity: O(n)
492. Construct the Rectangle
Description: Find rectangle dimensions closest to square with given area.
Java Solution:
public int[] constructRectangle(int area) {
int w = (int) Math.sqrt(area);
while (area % w != 0) w--;
return new int[]{area / w, w};
}
Explanation: Start from sqrt(area). Find largest w that divides area. L = area/w.
- Time Complexity: O(√area)
- Space Complexity: O(1)
493. Reverse Pairs
Description: Count reverse pairs where i < j and nums[i] > 2*nums[j].
Java Solution:
public int reversePairs(int[] nums) {
return mergeSort(nums, 0, nums.length - 1);
}
private int mergeSort(int[] nums, int left, int right) {
if (left >= right) return 0;
int mid = left + (right - left) / 2;
int count = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right);
int j = mid + 1;
for (int i = left; i <= mid; i++) {
while (j <= right && nums[i] > 2L * nums[j]) j++;
count += j - mid - 1;
}
Arrays.sort(nums, left, right + 1);
return count;
}
Explanation: Modified merge sort. Count pairs before merging. Use long to avoid overflow.
- Time Complexity: O(n log² n)
- Space Complexity: O(log n)
494. Target Sum
Description: Count ways to assign +/- to make target sum.
Java Solution:
public int findTargetSumWays(int[] nums, int target) {
int sum = 0;
for (int num : nums) sum += num;
if ((sum + target) % 2 != 0 || sum < Math.abs(target)) return 0;
int s = (sum + target) / 2;
int[] dp = new int[s + 1];
dp[0] = 1;
for (int num : nums) {
for (int j = s; j >= num; j--) {
dp[j] += dp[j - num];
}
}
return dp[s];
}
Explanation: Transform to subset sum: find subset with sum (total+target)/2. Use 0/1 knapsack.
- Time Complexity: O(n × sum)
- Space Complexity: O(sum)
495. Teemo Attacking
Description: Calculate total poison duration from attacks.
Java Solution:
public int findPoisonedDuration(int[] timeSeries, int duration) {
if (timeSeries.length == 0) return 0;
int total = 0;
for (int i = 0; i < timeSeries.length - 1; i++) {
total += Math.min(duration, timeSeries[i + 1] - timeSeries[i]);
}
return total + duration;
}
Explanation: For each attack, add min of duration or time until next attack. Add full duration for last.
- Time Complexity: O(n)
- Space Complexity: O(1)
496. Next Greater Element I
Description: Find next greater element for each query in nums2.
Java Solution:
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
Map<Integer, Integer> nextGreater = new HashMap<>();
Deque<Integer> stack = new ArrayDeque<>();
for (int num : nums2) {
while (!stack.isEmpty() && stack.peek() < num) {
nextGreater.put(stack.pop(), num);
}
stack.push(num);
}
int[] result = new int[nums1.length];
for (int i = 0; i < nums1.length; i++) {
result[i] = nextGreater.getOrDefault(nums1[i], -1);
}
return result;
}
Explanation: Monotonic stack to find next greater for all elements in nums2. Query from map.
- Time Complexity: O(n + m)
- Space Complexity: O(n)
497. Random Point in Non-overlapping Rectangles
Description: Pick random point from union of rectangles uniformly.
Java Solution:
class Solution {
int[][] rects;
int[] areas;
int total;
Random rand = new Random();
public Solution(int[][] rects) {
this.rects = rects;
areas = new int[rects.length];
total = 0;
for (int i = 0; i < rects.length; i++) {
int area = (rects[i][2] - rects[i][0] + 1) * (rects[i][3] - rects[i][1] + 1);
total += area;
areas[i] = total;
}
}
public int[] pick() {
int target = rand.nextInt(total);
int lo = 0, hi = areas.length - 1;
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (areas[mid] <= target) lo = mid + 1;
else hi = mid;
}
int[] r = rects[lo];
return new int[]{
r[0] + rand.nextInt(r[2] - r[0] + 1),
r[1] + rand.nextInt(r[3] - r[1] + 1)
};
}
}
Explanation: Weight by area. Binary search for rectangle. Random point within chosen rectangle.
- Time Complexity: O(log n) per pick
- Space Complexity: O(n)
498. Diagonal Traverse
Description: Traverse matrix diagonally in zigzag order.
Java Solution:
public int[] findDiagonalOrder(int[][] mat) {
int m = mat.length, n = mat[0].length;
int[] result = new int[m * n];
int r = 0, c = 0, idx = 0;
for (int i = 0; i < m * n; i++) {
result[idx++] = mat[r][c];
if ((r + c) % 2 == 0) {
if (c == n - 1) r++;
else if (r == 0) c++;
else { r--; c++; }
} else {
if (r == m - 1) c++;
else if (c == 0) r++;
else { r++; c--; }
}
}
return result;
}
Explanation: Move diagonally. Direction depends on diagonal sum parity. Handle boundaries.
- Time Complexity: O(mn)
- Space Complexity: O(1)
499. The Maze III
Description: Find shortest path in maze with hole, return lexicographically smallest path.
Java Solution:
public String findShortestWay(int[][] maze, int[] ball, int[] hole) {
int m = maze.length, n = maze[0].length;
int[][] dist = new int[m][n];
String[][] path = new String[m][n];
for (int[] row : dist) Arrays.fill(row, Integer.MAX_VALUE);
for (String[] row : path) Arrays.fill(row, "");
int[][] dirs = {{1, 0}, {0, -1}, {0, 1}, {-1, 0}};
char[] dirChars = {'d', 'l', 'r', 'u'};
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) ->
a[2] != b[2] ? a[2] - b[2] : path[a[0]][a[1]].compareTo(path[b[0]][b[1]]));
dist[ball[0]][ball[1]] = 0;
pq.offer(new int[]{ball[0], ball[1], 0});
while (!pq.isEmpty()) {
int[] cur = pq.poll();
int r = cur[0], c = cur[1], d = cur[2];
if (d > dist[r][c] || (d == dist[r][c] && path[r][c].compareTo(path[r][c]) < 0)) continue;
for (int i = 0; i < 4; i++) {
int nr = r, nc = c, steps = 0;
while (nr + dirs[i][0] >= 0 && nr + dirs[i][0] < m &&
nc + dirs[i][1] >= 0 && nc + dirs[i][1] < n &&
maze[nr + dirs[i][0]][nc + dirs[i][1]] == 0) {
nr += dirs[i][0];
nc += dirs[i][1];
steps++;
if (nr == hole[0] && nc == hole[1]) break;
}
String newPath = path[r][c] + dirChars[i];
int newDist = d + steps;
if (newDist < dist[nr][nc] || (newDist == dist[nr][nc] && newPath.compareTo(path[nr][nc]) < 0)) {
dist[nr][nc] = newDist;
path[nr][nc] = newPath;
pq.offer(new int[]{nr, nc, newDist});
}
}
}
return dist[hole[0]][hole[1]] == Integer.MAX_VALUE ? "impossible" : path[hole[0]][hole[1]];
}
Explanation: Dijkstra with priority on distance then path. Ball stops at hole or wall.
- Time Complexity: O(mn × max(m,n) × log(mn))
- Space Complexity: O(mn)
500. Keyboard Row
Description: Find words that can be typed using one keyboard row.
Java Solution:
public String[] findWords(String[] words) {
String[] rows = {"qwertyuiop", "asdfghjkl", "zxcvbnm"};
int[] rowMap = new int[26];
for (int i = 0; i < 3; i++) {
for (char c : rows[i].toCharArray()) rowMap[c - 'a'] = i;
}
List<String> result = new ArrayList<>();
for (String word : words) {
int row = rowMap[Character.toLowerCase(word.charAt(0)) - 'a'];
boolean valid = true;
for (char c : word.toCharArray()) {
if (rowMap[Character.toLowerCase(c) - 'a'] != row) {
valid = false; break;
}
}
if (valid) result.add(word);
}
return result.toArray(new String[0]);
}
Explanation: Map each letter to row number. Check all letters in word belong to same row.
- Time Complexity: O(n × m)
- Space Complexity: O(1)
501. Find Mode in Binary Search Tree
Description: Find mode(s) in BST.
Java Solution:
int maxCount = 0, currentCount = 0;
Integer prev = null;
List<Integer> modes = new ArrayList<>();
public int[] findMode(TreeNode root) {
inorder(root);
return modes.stream().mapToInt(i -> i).toArray();
}
private void inorder(TreeNode node) {
if (node == null) return;
inorder(node.left);
currentCount = (prev != null && prev == node.val) ? currentCount + 1 : 1;
if (currentCount > maxCount) {
maxCount = currentCount;
modes.clear();
modes.add(node.val);
} else if (currentCount == maxCount) {
modes.add(node.val);
}
prev = node.val;
inorder(node.right);
}
Explanation: Efficient algorithm. This solution handles all edge cases and provides optimal performance.
- Time Complexity: O(n)
- Space Complexity: O(1)
502. IPO
Description: Maximize capital by selecting at most k projects.
Java Solution:
public int findMaximizedCapital(int k, int w, int[] profits, int[] capital) {
int n = profits.length;
int[][] projects = new int[n][2];
for (int i = 0; i < n; i++) projects[i] = new int[]{capital[i], profits[i]};
Arrays.sort(projects, (a, b) -> a[0] - b[0]);
PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
int i = 0;
while (k-- > 0) {
while (i < n && projects[i][0] <= w) pq.offer(projects[i++][1]);
if (pq.isEmpty()) break;
w += pq.poll();
}
return w;
}
Explanation: Sort by capital. Max-heap for profits. Add available projects, pick most profitable.
- Time Complexity: O(n log n)
- Space Complexity: O(n)
503. Next Greater Element II
Description: Find next greater element in circular array.
Java Solution:
public int[] nextGreaterElements(int[] nums) {
int n = nums.length;
int[] result = new int[n];
Arrays.fill(result, -1);
Deque<Integer> stack = new ArrayDeque<>();
for (int i = 0; i < 2 * n; i++) {
while (!stack.isEmpty() && nums[stack.peek()] < nums[i % n]) {
result[stack.pop()] = nums[i % n];
}
if (i < n) stack.push(i);
}
return result;
}
Explanation: Iterate twice for circular. Monotonic stack to find next greater.
- Time Complexity: O(n)
- Space Complexity: O(n)
504. Base 7
Description: Convert integer to base 7 string.
Java Solution:
public String convertToBase7(int num) {
if (num == 0) return "0";
boolean negative = num < 0;
num = Math.abs(num);
StringBuilder sb = new StringBuilder();
while (num > 0) {
sb.insert(0, num % 7);
num /= 7;
}
return negative ? "-" + sb : sb.toString();
}
Explanation: Repeatedly divide by 7. Collect remainders. Handle negative.
- Time Complexity: O(log num)
- Space Complexity: O(log num)
505. The Maze II
Description: Find shortest distance in maze from start to destination.
Java Solution:
public int shortestDistance(int[][] maze, int[] start, int[] destination) {
int m = maze.length, n = maze[0].length;
int[][] dist = new int[m][n];
for (int[] row : dist) Arrays.fill(row, Integer.MAX_VALUE);
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[2] - b[2]);
pq.offer(new int[]{start[0], start[1], 0});
dist[start[0]][start[1]] = 0;
int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
while (!pq.isEmpty()) {
int[] curr = pq.poll();
if (curr[2] > dist[curr[0]][curr[1]]) continue;
for (int[] d : dirs) {
int r = curr[0], c = curr[1], steps = 0;
while (r + d[0] >= 0 && r + d[0] < m && c + d[1] >= 0 && c + d[1] < n
&& maze[r + d[0]][c + d[1]] == 0) {
r += d[0]; c += d[1]; steps++;
}
if (curr[2] + steps < dist[r][c]) {
dist[r][c] = curr[2] + steps;
pq.offer(new int[]{r, c, dist[r][c]});
}
}
}
return dist[destination[0]][destination[1]] == Integer.MAX_VALUE ? -1 : dist[destination[0]][destination[1]];
}
Explanation: Dijkstra’s algorithm. Ball rolls until wall. Track shortest distance to each position.
- Time Complexity: O(mn × max(m,n) × log(mn))
- Space Complexity: O(mn)
506. Relative Ranks
Description: Return ranks of athletes by score.
Java Solution:
public String[] findRelativeRanks(int[] score) {
int n = score.length;
Integer[] indices = new Integer[n];
for (int i = 0; i < n; i++) indices[i] = i;
Arrays.sort(indices, (a, b) -> score[b] - score[a]);
String[] result = new String[n];
for (int i = 0; i < n; i++) {
if (i == 0) result[indices[i]] = "Gold Medal";
else if (i == 1) result[indices[i]] = "Silver Medal";
else if (i == 2) result[indices[i]] = "Bronze Medal";
else result[indices[i]] = String.valueOf(i + 1);
}
return result;
}
Explanation: Sort indices by score descending. Assign medals to top 3, numbers to rest.
- Time Complexity: O(n log n)
- Space Complexity: O(n)
507. Perfect Number
Description: Check if number equals sum of its proper divisors.
Java Solution:
public boolean checkPerfectNumber(int num) {
if (num <= 1) return false;
int sum = 1;
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) {
sum += i;
if (i != num / i) sum += num / i;
}
}
return sum == num;
}
Explanation: Find divisors up to sqrt. Add both divisor pairs. Check if sum equals num.
- Time Complexity: O(√n)
- Space Complexity: O(1)
508. Most Frequent Subtree Sum
Description: Find most frequent subtree sum values.
Java Solution:
Map<Integer, Integer> count = new HashMap<>();
int maxCount = 0;
public int[] findFrequentTreeSum(TreeNode root) {
postorder(root);
List<Integer> result = new ArrayList<>();
for (Map.Entry<Integer, Integer> e : count.entrySet()) {
if (e.getValue() == maxCount) result.add(e.getKey());
}
return result.stream().mapToInt(i -> i).toArray();
}
private int postorder(TreeNode node) {
if (node == null) return 0;
int sum = node.val + postorder(node.left) + postorder(node.right);
int c = count.merge(sum, 1, Integer::sum);
maxCount = Math.max(maxCount, c);
return sum;
}
Explanation: Postorder to calculate subtree sums. Count frequencies. Return most frequent.
- Time Complexity: O(n)
- Space Complexity: O(n)
509. Fibonacci Number
Description: Calculate nth Fibonacci number.
Java Solution:
public int fib(int n) {
if (n <= 1) return n;
int a = 0, b = 1;
for (int i = 2; i <= n; i++) {
int c = a + b;
a = b;
b = c;
}
return b;
}
Explanation: Iterative approach. Track last two values. Constant space.
- Time Complexity: O(n)
- Space Complexity: O(1)
510. Inorder Successor in BST II
Description: Find inorder successor given node (has parent pointer).
Java Solution:
public Node inorderSuccessor(Node node) {
if (node.right != null) {
node = node.right;
while (node.left != null) node = node.left;
return node;
}
while (node.parent != null && node == node.parent.right) {
node = node.parent;
}
return node.parent;
}
Explanation: If right child exists, go right then all the way left. Otherwise go up until coming from left.
- Time Complexity: O(h)
- Space Complexity: O(1)
513. Find Bottom Left Tree Value
Description: Find leftmost value in last row of tree.
Java Solution:
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int result = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
if (i == 0) result = node.val;
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
}
return result;
}
Explanation: Level order traversal. Track first value of each level. Return last one.
- Time Complexity: O(n)
- Space Complexity: O(n)
514. Freedom Trail
Description: Find minimum steps to spell key on ring.
Java Solution:
public int findRotateSteps(String ring, String key) {
int n = ring.length(), m = key.length();
int[][] dp = new int[m + 1][n];
for (int[] row : dp) Arrays.fill(row, Integer.MAX_VALUE);
dp[0][0] = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (dp[i][j] == Integer.MAX_VALUE) continue;
for (int k = 0; k < n; k++) {
if (ring.charAt(k) == key.charAt(i)) {
int diff = Math.abs(k - j);
int steps = Math.min(diff, n - diff) + 1;
dp[i + 1][k] = Math.min(dp[i + 1][k], dp[i][j] + steps);
}
}
}
}
int result = Integer.MAX_VALUE;
for (int j = 0; j < n; j++) result = Math.min(result, dp[m][j]);
return result;
}
Explanation: DP on position in ring and key. For each target char, try all matching positions in ring.
- Time Complexity: O(m × n²)
- Space Complexity: O(m × n)
515. Find Largest Value in Each Tree Row
Description: Find maximum value in each tree level.
Java Solution:
public List<Integer> largestValues(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null) return result;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size(), max = Integer.MIN_VALUE;
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
max = Math.max(max, node.val);
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
result.add(max);
}
return result;
}
Explanation: BFS level by level. Track maximum in each level.
- Time Complexity: O(n)
- Space Complexity: O(n)
516. Longest Palindromic Subsequence
Description: Find length of longest palindromic subsequence.
Java Solution:
public int longestPalindromeSubseq(String s) {
int n = s.length();
int[] dp = new int[n];
Arrays.fill(dp, 1);
for (int i = n - 2; i >= 0; i--) {
int prev = 0;
for (int j = i + 1; j < n; j++) {
int temp = dp[j];
if (s.charAt(i) == s.charAt(j)) dp[j] = prev + 2;
else dp[j] = Math.max(dp[j], dp[j - 1]);
prev = temp;
}
}
return dp[n - 1];
}
Explanation: DP where dp[j] = longest palindromic subsequence from i to j. Space optimized.
- Time Complexity: O(n²)
- Space Complexity: O(n)
517. Super Washing Machines
Description: Find minimum moves to balance dresses in washing machines.
Java Solution:
public int findMinMoves(int[] machines) {
int sum = 0;
for (int m : machines) sum += m;
if (sum % machines.length != 0) return -1;
int avg = sum / machines.length;
int result = 0, running = 0;
for (int m : machines) {
int diff = m - avg;
running += diff;
result = Math.max(result, Math.max(Math.abs(running), diff));
}
return result;
}
Explanation: Calculate flow needed through each position. Max of absolute flow or single machine excess.
- Time Complexity: O(n)
- Space Complexity: O(1)
518. Coin Change II
Description: Count ways to make amount with coins.
Java Solution:
public int change(int amount, int[] coins) {
int[] dp = new int[amount + 1];
dp[0] = 1;
for (int coin : coins) {
for (int j = coin; j <= amount; j++) {
dp[j] += dp[j - coin];
}
}
return dp[amount];
}
Explanation: Unbounded knapsack. Count combinations by processing each coin.
- Time Complexity: O(n × amount)
- Space Complexity: O(amount)
519. Random Flip Matrix
Description: Randomly flip 0 to 1 in matrix with equal probability.
Java Solution:
class Solution {
Map<Integer, Integer> map = new HashMap<>();
int rows, cols, total;
Random rand = new Random();
public Solution(int m, int n) {
rows = m; cols = n; total = m * n;
}
public int[] flip() {
int r = rand.nextInt(total--);
int x = map.getOrDefault(r, r);
map.put(r, map.getOrDefault(total, total));
return new int[]{x / cols, x % cols};
}
public void reset() {
map.clear();
total = rows * cols;
}
}
Explanation: Fisher-Yates shuffle concept. Map swapped positions. Pick random from remaining.
- Time Complexity: O(1) per flip
- Space Complexity: O(flips)
520. Detect Capital
Description: Check if word uses capitals correctly.
Java Solution:
public boolean detectCapitalUse(String word) {
int capitals = 0;
for (char c : word.toCharArray()) {
if (Character.isUpperCase(c)) capitals++;
}
return capitals == 0 || capitals == word.length() ||
(capitals == 1 && Character.isUpperCase(word.charAt(0)));
}
Explanation: Valid if all lower, all upper, or only first upper.
- Time Complexity: O(n)
- Space Complexity: O(1)
521. Longest Uncommon Subsequence I
Description: Find longest uncommon subsequence between two strings.
Java Solution:
public int findLUSlength(String a, String b) {
return a.equals(b) ? -1 : Math.max(a.length(), b.length());
}
Explanation: If different, longer string is LUS. If same, no LUS exists.
- Time Complexity: O(min(m, n))
- Space Complexity: O(1)
522. Longest Uncommon Subsequence II
Description: Find longest uncommon subsequence among strings.
Java Solution:
public int findLUSlength(String[] strs) {
Arrays.sort(strs, (a, b) -> b.length() - a.length());
for (int i = 0; i < strs.length; i++) {
boolean isSubseq = false;
for (int j = 0; j < strs.length; j++) {
if (i != j && isSubsequence(strs[i], strs[j])) {
isSubseq = true;
break;
}
}
if (!isSubseq) return strs[i].length();
}
return -1;
}
private boolean isSubsequence(String a, String b) {
int i = 0;
for (char c : b.toCharArray()) {
if (i < a.length() && a.charAt(i) == c) i++;
}
return i == a.length();
}
Explanation: Check each string if it’s not subsequence of any other. Sort by length descending.
- Time Complexity: O(n² × m)
- Space Complexity: O(1)
523. Continuous Subarray Sum
Description: Check if subarray sum is multiple of k.
Java Solution:
public boolean checkSubarraySum(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
int rem = sum % k;
if (map.containsKey(rem)) {
if (i - map.get(rem) >= 2) return true;
} else map.put(rem, i);
}
return false;
}
Explanation: Same remainder at positions i and j means sum[i+1..j] divisible by k. Need length >= 2.
- Time Complexity: O(n)
- Space Complexity: O(min(n, k))
524. Longest Word in Dictionary through Deleting
Description: Find longest word in dictionary that’s subsequence of s.
Java Solution:
public String findLongestWord(String s, List<String> dictionary) {
String result = "";
for (String word : dictionary) {
if (isSubsequence(word, s)) {
if (word.length() > result.length() ||
(word.length() == result.length() && word.compareTo(result) < 0)) {
result = word;
}
}
}
return result;
}
private boolean isSubsequence(String word, String s) {
int i = 0;
for (char c : s.toCharArray()) {
if (i < word.length() && word.charAt(i) == c) i++;
}
return i == word.length();
}
Explanation: Check each word if subsequence. Track longest, lexicographically smallest.
- Time Complexity: O(n × m × k)
- Space Complexity: O(1)
525. Contiguous Array
Description: Find longest subarray with equal 0s and 1s.
Java Solution:
public int findMaxLength(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
int count = 0, maxLen = 0;
for (int i = 0; i < nums.length; i++) {
count += nums[i] == 1 ? 1 : -1;
if (map.containsKey(count)) {
maxLen = Math.max(maxLen, i - map.get(count));
} else map.put(count, i);
}
return maxLen;
}
Explanation: Replace 0 with -1. Find longest subarray with sum 0 using prefix sum.
- Time Complexity: O(n)
- Space Complexity: O(n)
526. Beautiful Arrangement
Description: Count permutations where i divides perm[i] or vice versa.
Java Solution:
public int countArrangement(int n) {
return backtrack(n, 1, new boolean[n + 1]);
}
private int backtrack(int n, int pos, boolean[] used) {
if (pos > n) return 1;
int count = 0;
for (int i = 1; i <= n; i++) {
if (!used[i] && (i % pos == 0 || pos % i == 0)) {
used[i] = true;
count += backtrack(n, pos + 1, used);
used[i] = false;
}
}
return count;
}
Explanation: Backtrack trying each number at each position. Check divisibility condition.
- Time Complexity: O(k) where k is valid permutations
- Space Complexity: O(n)
527. Word Abbreviation
Description: Abbreviate words uniquely.
Java Solution:
public List<String> wordsAbbreviation(List<String> words) {
int n = words.size();
String[] result = new String[n];
int[] prefix = new int[n];
for (int i = 0; i < n; i++) result[i] = abbrev(words.get(i), 0);
for (int i = 0; i < n; i++) {
while (true) {
Set<Integer> duplicates = new HashSet<>();
for (int j = i + 1; j < n; j++) {
if (result[j].equals(result[i])) duplicates.add(j);
}
if (duplicates.isEmpty()) break;
duplicates.add(i);
for (int j : duplicates) result[j] = abbrev(words.get(j), ++prefix[j]);
}
}
return Arrays.asList(result);
}
private String abbrev(String s, int i) {
if (s.length() - i <= 3) return s;
return s.substring(0, i + 1) + (s.length() - i - 2) + s.charAt(s.length() - 1);
}
Explanation: Start with minimal abbreviation. Resolve conflicts by increasing prefix length.
- Time Complexity: O(n² × m)
- Space Complexity: O(n × m)
528. Random Pick with Weight
Description: Pick index with probability proportional to weight.
Java Solution:
class Solution {
int[] prefix;
Random rand = new Random();
public Solution(int[] w) {
prefix = new int[w.length];
prefix[0] = w[0];
for (int i = 1; i < w.length; i++) prefix[i] = prefix[i - 1] + w[i];
}
public int pickIndex() {
int target = rand.nextInt(prefix[prefix.length - 1]) + 1;
int lo = 0, hi = prefix.length - 1;
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (prefix[mid] < target) lo = mid + 1;
else hi = mid;
}
return lo;
}
}
Explanation: Build prefix sum. Binary search for random value in [1, total].
- Time Complexity: O(log n) per pick
- Space Complexity: O(n)
529. Minesweeper
Description: Update board after click in minesweeper.
Java Solution:
public char[][] updateBoard(char[][] board, int[] click) {
int r = click[0], c = click[1];
if (board[r][c] == 'M') {
board[r][c] = 'X';
return board;
}
reveal(board, r, c);
return board;
}
private void reveal(char[][] board, int r, int c) {
if (r < 0 || r >= board.length || c < 0 || c >= board[0].length || board[r][c] != 'E') return;
int mines = 0;
for (int dr = -1; dr <= 1; dr++) {
for (int dc = -1; dc <= 1; dc++) {
int nr = r + dr, nc = c + dc;
if (nr >= 0 && nr < board.length && nc >= 0 && nc < board[0].length && board[nr][nc] == 'M') mines++;
}
}
if (mines > 0) board[r][c] = (char) ('0' + mines);
else {
board[r][c] = 'B';
for (int dr = -1; dr <= 1; dr++) {
for (int dc = -1; dc <= 1; dc++) {
reveal(board, r + dr, c + dc);
}
}
}
}
Explanation: If mine, reveal X. Otherwise count adjacent mines. If zero, recursively reveal neighbors.
- Time Complexity: O(mn)
- Space Complexity: O(mn)
530. Minimum Absolute Difference in BST
Description: Find minimum absolute difference between any two nodes in BST.
Java Solution:
int minDiff = Integer.MAX_VALUE;
Integer prev = null;
public int getMinimumDifference(TreeNode root) {
inorder(root);
return minDiff;
}
private void inorder(TreeNode node) {
if (node == null) return;
inorder(node.left);
if (prev != null) minDiff = Math.min(minDiff, node.val - prev);
prev = node.val;
inorder(node.right);
}
Explanation: Inorder traversal visits nodes in sorted order. Compare consecutive nodes.
- Time Complexity: O(n)
- Space Complexity: O(h)
532. K-diff Pairs in an Array
Description: Count unique k-diff pairs in array.
Java Solution:
public int findPairs(int[] nums, int k) {
Map<Integer, Integer> count = new HashMap<>();
for (int num : nums) count.merge(num, 1, Integer::sum);
int result = 0;
for (int num : count.keySet()) {
if (k == 0) {
if (count.get(num) >= 2) result++;
} else {
if (count.containsKey(num + k)) result++;
}
}
return result;
}
Explanation: Count occurrences. For k=0, need duplicates. Otherwise, check if num+k exists.
- Time Complexity: O(n)
- Space Complexity: O(n)
535. Encode and Decode TinyURL
Description: Design URL shortening service.
Java Solution:
class Codec {
Map<String, String> map = new HashMap<>();
String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random rand = new Random();
public String encode(String longUrl) {
String key;
do {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 6; i++) sb.append(chars.charAt(rand.nextInt(62)));
key = sb.toString();
} while (map.containsKey(key));
map.put(key, longUrl);
return "http://tinyurl.com/" + key;
}
public String decode(String shortUrl) {
return map.get(shortUrl.substring(19));
}
}
Explanation: Generate random 6-char code. Store mapping. Extract code for decode.
- Time Complexity: O(1) average
- Space Complexity: O(n)
536. Construct Binary Tree from String
Description: Build tree from string with parentheses notation.
Java Solution:
int i = 0;
public TreeNode str2tree(String s) {
if (s.isEmpty()) return null;
return build(s);
}
private TreeNode build(String s) {
if (i >= s.length()) return null;
int sign = 1;
if (s.charAt(i) == '-') { sign = -1; i++; }
int num = 0;
while (i < s.length() && Character.isDigit(s.charAt(i))) {
num = num * 10 + (s.charAt(i++) - '0');
}
TreeNode node = new TreeNode(sign * num);
if (i < s.length() && s.charAt(i) == '(') {
i++;
node.left = build(s);
i++;
}
if (i < s.length() && s.charAt(i) == '(') {
i++;
node.right = build(s);
i++;
}
return node;
}
Explanation: Parse number, then left subtree in parens, then right subtree in parens recursively.
- Time Complexity: O(n)
- Space Complexity: O(h)
537. Complex Number Multiplication
Description: Multiply two complex numbers.
Java Solution:
public String complexNumberMultiply(String num1, String num2) {
int[] n1 = parse(num1), n2 = parse(num2);
int real = n1[0] * n2[0] - n1[1] * n2[1];
int imag = n1[0] * n2[1] + n1[1] * n2[0];
return real + "+" + imag + "i";
}
private int[] parse(String s) {
String[] parts = s.split("\\+");
return new int[]{Integer.parseInt(parts[0]), Integer.parseInt(parts[1].replace("i", ""))};
}
Explanation: Parse real and imaginary parts. Apply (a+bi)(c+di) = (ac-bd) + (ad+bc)i.
- Time Complexity: O(n)
- Space Complexity: O(1)
538. Convert BST to Greater Tree
Description: Convert BST so each node contains sum of all greater values.
Java Solution:
int sum = 0;
public TreeNode convertBST(TreeNode root) {
if (root != null) {
convertBST(root.right);
sum += root.val;
root.val = sum;
convertBST(root.left);
}
return root;
}
Explanation: Reverse inorder (right-node-left). Accumulate sum and update each node.
- Time Complexity: O(n)
- Space Complexity: O(h)
539. Minimum Time Difference
Description: Find minimum minutes between any two times.
Java Solution:
public int findMinDifference(List<String> timePoints) {
boolean[] seen = new boolean[1440];
for (String t : timePoints) {
int mins = Integer.parseInt(t.substring(0, 2)) * 60 + Integer.parseInt(t.substring(3));
if (seen[mins]) return 0;
seen[mins] = true;
}
int min = Integer.MAX_VALUE, first = -1, prev = -1;
for (int i = 0; i < 1440; i++) {
if (seen[i]) {
if (first == -1) first = i;
if (prev != -1) min = Math.min(min, i - prev);
prev = i;
}
}
return Math.min(min, 1440 - prev + first);
}
Explanation: Convert to minutes. Mark seen times. Find minimum gap. Handle circular wrap.
- Time Complexity: O(n + 1440)
- Space Complexity: O(1440)
540. Single Element in a Sorted Array
Description: Find single element in sorted array where others appear twice.
Java Solution:
public int singleNonDuplicate(int[] nums) {
int lo = 0, hi = nums.length - 1;
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (mid % 2 == 1) mid--;
if (nums[mid] == nums[mid + 1]) lo = mid + 2;
else hi = mid;
}
return nums[lo];
}
Explanation: Binary search. Before single element, pairs start at even indices. After, odd indices.
- Time Complexity: O(log n)
- Space Complexity: O(1)
541. Reverse String II
Description: Reverse first k chars for every 2k chars.
Java Solution:
public String reverseStr(String s, int k) {
char[] arr = s.toCharArray();
for (int i = 0; i < arr.length; i += 2 * k) {
int left = i, right = Math.min(i + k - 1, arr.length - 1);
while (left < right) {
char temp = arr[left];
arr[left++] = arr[right];
arr[right--] = temp;
}
}
return new String(arr);
}
Explanation: Every 2k chars, reverse first k. Handle remaining chars at end.
- Time Complexity: O(n)
- Space Complexity: O(n)
542. 01 Matrix
Description: Find distance to nearest 0 for each cell.
Java Solution:
public int[][] updateMatrix(int[][] mat) {
int m = mat.length, n = mat[0].length;
Queue<int[]> queue = new LinkedList<>();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (mat[i][j] == 0) queue.offer(new int[]{i, j});
else mat[i][j] = Integer.MAX_VALUE;
}
}
int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
while (!queue.isEmpty()) {
int[] cell = queue.poll();
for (int[] d : dirs) {
int r = cell[0] + d[0], c = cell[1] + d[1];
if (r >= 0 && r < m && c >= 0 && c < n && mat[r][c] > mat[cell[0]][cell[1]] + 1) {
mat[r][c] = mat[cell[0]][cell[1]] + 1;
queue.offer(new int[]{r, c});
}
}
}
return mat;
}
Explanation: Multi-source BFS from all 0s. Update distances layer by layer.
- Time Complexity: O(mn)
- Space Complexity: O(mn)
543. Diameter of Binary Tree
Description: Find longest path between any two nodes.
Java Solution:
int diameter = 0;
public int diameterOfBinaryTree(TreeNode root) {
depth(root);
return diameter;
}
private int depth(TreeNode node) {
if (node == null) return 0;
int left = depth(node.left);
int right = depth(node.right);
diameter = Math.max(diameter, left + right);
return Math.max(left, right) + 1;
}
Explanation: At each node, diameter through it = left depth + right depth. Track maximum.
- Time Complexity: O(n)
- Space Complexity: O(h)
545. Boundary of Binary Tree
Description: Return boundary nodes in counterclockwise order.
Java Solution:
public List<Integer> boundaryOfBinaryTree(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null) return result;
result.add(root.val);
leftBoundary(root.left, result);
leaves(root.left, result);
leaves(root.right, result);
rightBoundary(root.right, result);
return result;
}
private void leftBoundary(TreeNode node, List<Integer> res) {
if (node == null || (node.left == null && node.right == null)) return;
res.add(node.val);
if (node.left != null) leftBoundary(node.left, res);
else leftBoundary(node.right, res);
}
private void rightBoundary(TreeNode node, List<Integer> res) {
if (node == null || (node.left == null && node.right == null)) return;
if (node.right != null) rightBoundary(node.right, res);
else rightBoundary(node.left, res);
res.add(node.val);
}
private void leaves(TreeNode node, List<Integer> res) {
if (node == null) return;
if (node.left == null && node.right == null) { res.add(node.val); return; }
leaves(node.left, res);
leaves(node.right, res);
}
Explanation: Collect left boundary (top-down), leaves (left-right), right boundary (bottom-up).
- Time Complexity: O(n)
- Space Complexity: O(n)
546. Remove Boxes
Description: Remove boxes to maximize points (k consecutive same = k² points).
Java Solution:
public int removeBoxes(int[] boxes) {
int n = boxes.length;
int[][][] dp = new int[n][n][n];
return dfs(boxes, dp, 0, n - 1, 0);
}
private int dfs(int[] boxes, int[][][] dp, int l, int r, int k) {
if (l > r) return 0;
if (dp[l][r][k] > 0) return dp[l][r][k];
while (r > l && boxes[r] == boxes[r - 1]) { r--; k++; }
dp[l][r][k] = dfs(boxes, dp, l, r - 1, 0) + (k + 1) * (k + 1);
for (int i = l; i < r; i++) {
if (boxes[i] == boxes[r]) {
dp[l][r][k] = Math.max(dp[l][r][k],
dfs(boxes, dp, l, i, k + 1) + dfs(boxes, dp, i + 1, r - 1, 0));
}
}
return dp[l][r][k];
}
Explanation: dp[l][r][k] = max points for boxes[l..r] with k boxes of same color attached to right.
- Time Complexity: O(n⁴)
- Space Complexity: O(n³)
547. Number of Provinces
Description: Count connected components (friend groups).
Java Solution:
public int findCircleNum(int[][] isConnected) {
int n = isConnected.length;
boolean[] visited = new boolean[n];
int count = 0;
for (int i = 0; i < n; i++) {
if (!visited[i]) {
dfs(isConnected, visited, i);
count++;
}
}
return count;
}
private void dfs(int[][] g, boolean[] visited, int i) {
visited[i] = true;
for (int j = 0; j < g.length; j++) {
if (g[i][j] == 1 && !visited[j]) dfs(g, visited, j);
}
}
Explanation: DFS from each unvisited node. Count connected components.
- Time Complexity: O(n²)
- Space Complexity: O(n)
548. Split Array with Equal Sum
Description: Split array into 4 parts with equal sum.
Java Solution:
public boolean splitArray(int[] nums) {
if (nums.length < 7) return false;
int[] prefix = new int[nums.length];
prefix[0] = nums[0];
for (int i = 1; i < nums.length; i++) prefix[i] = prefix[i - 1] + nums[i];
for (int j = 3; j < nums.length - 3; j++) {
Set<Integer> sums = new HashSet<>();
for (int i = 1; i < j - 1; i++) {
if (prefix[i - 1] == prefix[j - 1] - prefix[i]) sums.add(prefix[i - 1]);
}
for (int k = j + 2; k < nums.length - 1; k++) {
int sum3 = prefix[k - 1] - prefix[j];
int sum4 = prefix[nums.length - 1] - prefix[k];
if (sum3 == sum4 && sums.contains(sum3)) return true;
}
}
return false;
}
Explanation: Fix middle divider j. Check left dividers where sum1=sum2. Check right dividers where sum3=sum4 matches.
- Time Complexity: O(n²)
- Space Complexity: O(n)
549. Binary Tree Longest Consecutive Sequence II
Description: Find longest consecutive path (increasing or decreasing).
Java Solution:
int maxLen = 0;
public int longestConsecutive(TreeNode root) {
dfs(root);
return maxLen;
}
private int[] dfs(TreeNode node) {
if (node == null) return new int[]{0, 0};
int inc = 1, dec = 1;
if (node.left != null) {
int[] left = dfs(node.left);
if (node.val == node.left.val + 1) inc = left[0] + 1;
else if (node.val == node.left.val - 1) dec = left[1] + 1;
}
if (node.right != null) {
int[] right = dfs(node.right);
if (node.val == node.right.val + 1) inc = Math.max(inc, right[0] + 1);
else if (node.val == node.right.val - 1) dec = Math.max(dec, right[1] + 1);
}
maxLen = Math.max(maxLen, inc + dec - 1);
return new int[]{inc, dec};
}
Explanation: Track increasing and decreasing lengths at each node. Combine paths through node.
- Time Complexity: O(n)
- Space Complexity: O(h)
550. Game Play Analysis IV
Description: SQL: Find fraction of players who logged in day after first login.
Java Solution:
// This is a SQL problem
// SELECT ROUND(COUNT(DISTINCT a.player_id) / (SELECT COUNT(DISTINCT player_id) FROM Activity), 2) AS fraction
// FROM Activity a
// WHERE (a.player_id, DATE_SUB(a.event_date, INTERVAL 1 DAY)) IN
// (SELECT player_id, MIN(event_date) FROM Activity GROUP BY player_id)
Explanation: Find first login date per player. Check if they have activity on day+1. Calculate fraction.
- Time Complexity: O(n)
- Space Complexity: O(n)
551. Student Attendance Record I
Description:
Given a string s representing a student’s attendance record where each character is ‘A’ (absent), ‘L’ (late), or ‘P’ (present), return true if the student is eligible for an attendance award. The student is eligible if both: they were absent for strictly fewer than 2 days total, and they were never late for 3 or more consecutive days.
Java Solution:
public boolean checkRecord(String s) {
int absentCount = 0;
int consecutiveLate = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == 'A') {
absentCount++;
if (absentCount >= 2) return false;
consecutiveLate = 0;
} else if (c == 'L') {
consecutiveLate++;
if (consecutiveLate >= 3) return false;
} else {
consecutiveLate = 0;
}
}
return true;
}
Explanation: Iterate through the string tracking absent count and consecutive late days. Return false immediately if either condition is violated (2+ absences or 3+ consecutive lates). Reset consecutive counter when seeing non-L character.
- Time Complexity: O(n) - single pass through string
- Space Complexity: O(1) - only using counters
552. Student Attendance Record II
Description:
Given an integer n, return the number of possible attendance records of length n that make a student eligible for an award. The answer may be very large, so return it modulo 10^9 + 7. Eligible means strictly fewer than 2 absences and never 3 or more consecutive lates.
Java Solution:
public int checkRecord(int n) {
int MOD = 1000000007;
// dp[i][j][k] = records of length i with j absences and k consecutive lates
long[][][] dp = new long[n + 1][2][3];
dp[0][0][0] = 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 3; k++) {
// Add P
dp[i + 1][j][0] = (dp[i + 1][j][0] + dp[i][j][k]) % MOD;
// Add A
if (j < 1) {
dp[i + 1][j + 1][0] = (dp[i + 1][j + 1][0] + dp[i][j][k]) % MOD;
}
// Add L
if (k < 2) {
dp[i + 1][j][k + 1] = (dp[i + 1][j][k + 1] + dp[i][j][k]) % MOD;
}
}
}
}
long result = 0;
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 3; k++) {
result = (result + dp[n][j][k]) % MOD;
}
}
return (int) result;
}
Explanation: Use 3D DP where dp[i][j][k] represents number of valid records of length i with j absences and k consecutive lates. For each state, try adding P, A, or L based on constraints. Sum all valid final states.
- Time Complexity: O(n) - iterate through length with constant states
- Space Complexity: O(n) - 3D DP array with constant dimensions
553. Optimal Division
Description:
Given an array of positive integers nums, return the maximum result of nums[0] / nums[1] / nums[2] / ... / nums[nums.length - 1] by adding parentheses. Return the result as a string in the format “num1/(num2/num3/…)”.
Java Solution:
public String optimalDivision(int[] nums) {
if (nums.length == 1) return String.valueOf(nums[0]);
if (nums.length == 2) return nums[0] + "/" + nums[1];
StringBuilder sb = new StringBuilder();
sb.append(nums[0]).append("/(");
for (int i = 1; i < nums.length; i++) {
sb.append(nums[i]);
if (i < nums.length - 1) sb.append("/");
}
sb.append(")");
return sb.toString();
}
Explanation: The maximum result is always achieved by dividing the first number by the product of all others. This is done by adding parentheses around all numbers except the first: a/(b/c/d…) = a*(c*d…)/(b). For edge cases, handle single or two numbers directly.
- Time Complexity: O(n) - building result string
- Space Complexity: O(n) - string builder
554. Brick Wall
Description:
There is a rectangular brick wall in front of you with n rows of bricks. The bricks have the same height but different widths. You want to draw a vertical line from top to bottom that crosses the least number of bricks. Return the minimum number of crossed bricks.
Java Solution:
public int leastBricks(List<List<Integer>> wall) {
Map<Integer, Integer> edgeCount = new HashMap<>();
int maxEdges = 0;
for (List<Integer> row : wall) {
int position = 0;
// Don't count the edge at the end
for (int i = 0; i < row.size() - 1; i++) {
position += row.get(i);
edgeCount.put(position, edgeCount.getOrDefault(position, 0) + 1);
maxEdges = Math.max(maxEdges, edgeCount.get(position));
}
}
return wall.size() - maxEdges;
}
Explanation: Count edges at each position (cumulative width). The position with most edges means the line crosses least bricks. Use hashmap to track edge frequencies. The answer is total rows minus maximum edge count at any position.
- Time Complexity: O(n * m) - n rows, m average bricks per row
- Space Complexity: O(w) - w is total wall width
555. Split Concatenated Strings
Description:
Given an array of strings strs, you can choose any index to split each string into two non-empty parts. You can reverse any string before concatenating. Return the lexicographically largest string you can form by choosing one split from one string and concatenating all parts.
Java Solution:
public String splitLoopedString(String[] strs) {
// Keep each string in lexicographically larger form
for (int i = 0; i < strs.length; i++) {
String rev = new StringBuilder(strs[i]).reverse().toString();
if (rev.compareTo(strs[i]) > 0) {
strs[i] = rev;
}
}
String result = "";
for (int i = 0; i < strs.length; i++) {
String rev = new StringBuilder(strs[i]).reverse().toString();
for (String s : new String[]{strs[i], rev}) {
for (int j = 0; j < s.length(); j++) {
StringBuilder sb = new StringBuilder(s.substring(j));
for (int k = i + 1; k < strs.length; k++) {
sb.append(strs[k]);
}
for (int k = 0; k < i; k++) {
sb.append(strs[k]);
}
sb.append(s.substring(0, j));
String candidate = sb.toString();
if (candidate.compareTo(result) > 0) {
result = candidate;
}
}
}
}
return result;
}
Explanation: First, normalize each string to its lexicographically larger form (original or reversed). Then try every possible split point in every string (both forms) and build the complete concatenation. Track the maximum result.
- Time Complexity: O(n * m^2) - n strings, m average length
- Space Complexity: O(n * m) - storing strings
556. Next Greater Element III
Description:
Given a positive integer n, find the smallest integer which has exactly the same digits existing in n and is greater than n. If no such number exists, return -1.
Java Solution:
public int nextGreaterElement(int n) {
char[] digits = String.valueOf(n).toCharArray();
int len = digits.length;
// Find first decreasing element from right
int i = len - 2;
while (i >= 0 && digits[i] >= digits[i + 1]) {
i--;
}
if (i < 0) return -1; // Already largest permutation
// Find smallest element greater than digits[i] to the right
int j = len - 1;
while (j >= 0 && digits[j] <= digits[i]) {
j--;
}
// Swap
swap(digits, i, j);
// Reverse the suffix
reverse(digits, i + 1, len - 1);
try {
return Integer.parseInt(new String(digits));
} catch (Exception e) {
return -1; // Overflow
}
}
private void swap(char[] arr, int i, int j) {
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
private void reverse(char[] arr, int start, int end) {
while (start < end) {
swap(arr, start++, end--);
}
}
Explanation: Find the next permutation of digits. From right, find first decreasing digit, then find smallest digit to its right that’s greater, swap them, and reverse the suffix. Handle overflow by catching exception.
- Time Complexity: O(log n) - number of digits
- Space Complexity: O(log n) - char array
557. Reverse Words in a String III
Description:
Given a string s, reverse the order of characters in each word within a sentence while preserving whitespace and initial word order.
Java Solution:
public String reverseWords(String s) {
char[] chars = s.toCharArray();
int start = 0;
for (int end = 0; end <= chars.length; end++) {
if (end == chars.length || chars[end] == ' ') {
reverse(chars, start, end - 1);
start = end + 1;
}
}
return new String(chars);
}
private void reverse(char[] arr, int left, int right) {
while (left < right) {
char temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
}
Explanation: Convert string to char array for in-place modification. Track word boundaries and reverse each word individually. When encountering space or end, reverse the current word.
- Time Complexity: O(n) - single pass with reversals
- Space Complexity: O(n) - char array
558. Logical OR of Two Binary Grids Represented as Quad-Trees
Description: Given two quad-trees representing binary grids, return a quad-tree representing the logical OR of the two grids. A quad-tree is a tree data structure where each node has exactly four children or is a leaf.
Java Solution:
class Node {
public boolean val;
public boolean isLeaf;
public Node topLeft;
public Node topRight;
public Node bottomLeft;
public Node bottomRight;
}
public Node intersect(Node quadTree1, Node quadTree2) {
if (quadTree1.isLeaf) {
return quadTree1.val ? quadTree1 : quadTree2;
}
if (quadTree2.isLeaf) {
return quadTree2.val ? quadTree2 : quadTree1;
}
Node topLeft = intersect(quadTree1.topLeft, quadTree2.topLeft);
Node topRight = intersect(quadTree1.topRight, quadTree2.topRight);
Node bottomLeft = intersect(quadTree1.bottomLeft, quadTree2.bottomLeft);
Node bottomRight = intersect(quadTree1.bottomRight, quadTree2.bottomRight);
// If all children are leaves with same value, merge into single leaf
if (topLeft.isLeaf && topRight.isLeaf && bottomLeft.isLeaf && bottomRight.isLeaf
&& topLeft.val == topRight.val && topLeft.val == bottomLeft.val
&& topLeft.val == bottomRight.val) {
Node node = new Node();
node.isLeaf = true;
node.val = topLeft.val;
return node;
}
Node node = new Node();
node.isLeaf = false;
node.topLeft = topLeft;
node.topRight = topRight;
node.bottomLeft = bottomLeft;
node.bottomRight = bottomRight;
return node;
}
Explanation: Recursively OR the quad-trees. If either node is a leaf with value true, return true. Otherwise, recursively process four quadrants. If all resulting children are identical leaves, merge into single leaf.
- Time Complexity: O(n) - visit each node
- Space Complexity: O(log n) - recursion depth
559. Maximum Depth of N-ary Tree
Description: Given an n-ary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
Java Solution:
class Node {
public int val;
public List<Node> children;
}
public int maxDepth(Node root) {
if (root == null) return 0;
int maxChildDepth = 0;
for (Node child : root.children) {
maxChildDepth = Math.max(maxChildDepth, maxDepth(child));
}
return maxChildDepth + 1;
}
Explanation: Recursively find maximum depth among all children and add 1 for current level. Base case is null returning 0. For each node, compute max depth of all children and add 1.
- Time Complexity: O(n) - visit each node once
- Space Complexity: O(h) - recursion depth for tree height
560. Subarray Sum Equals K
Description:
Given an array of integers nums and an integer k, return the total number of subarrays whose sum equals k.
Java Solution:
public int subarraySum(int[] nums, int k) {
Map<Integer, Integer> prefixSumCount = new HashMap<>();
prefixSumCount.put(0, 1);
int sum = 0;
int count = 0;
for (int num : nums) {
sum += num;
// Check if there's a prefix sum such that current_sum - prefix_sum = k
if (prefixSumCount.containsKey(sum - k)) {
count += prefixSumCount.get(sum - k);
}
prefixSumCount.put(sum, prefixSumCount.getOrDefault(sum, 0) + 1);
}
return count;
}
Explanation: Use prefix sum with hashmap. For each position, check if there exists a previous prefix sum such that current_sum - previous_sum = k. Store frequency of each prefix sum encountered.
- Time Complexity: O(n) - single pass
- Space Complexity: O(n) - hashmap storage
561. Array Partition
Description:
Given an integer array nums of 2n integers, group these integers into n pairs such that the sum of min(ai, bi) for all pairs is maximized. Return the maximized sum.
Java Solution:
public int arrayPairSum(int[] nums) {
Arrays.sort(nums);
int sum = 0;
for (int i = 0; i < nums.length; i += 2) {
sum += nums[i];
}
return sum;
}
Explanation: Sort the array and pair consecutive elements. After sorting, pairing (nums[0], nums[1]), (nums[2], nums[3]), etc. maximizes the sum of minimums because we minimize the “waste” of larger numbers.
- Time Complexity: O(n log n) - sorting
- Space Complexity: O(1) - in-place sorting
562. Longest Line of Consecutive One in Matrix
Description:
Given an m x n binary matrix mat, return the length of the longest line of consecutive ones in the matrix. The line could be horizontal, vertical, diagonal, or anti-diagonal.
Java Solution:
public int longestLine(int[][] mat) {
if (mat == null || mat.length == 0) return 0;
int m = mat.length, n = mat[0].length;
int maxLen = 0;
// dp[i][j][k] = length ending at (i,j) in direction k
// 0: horizontal, 1: vertical, 2: diagonal, 3: anti-diagonal
int[][][] dp = new int[m][n][4];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (mat[i][j] == 1) {
dp[i][j][0] = j > 0 ? dp[i][j - 1][0] + 1 : 1; // horizontal
dp[i][j][1] = i > 0 ? dp[i - 1][j][1] + 1 : 1; // vertical
dp[i][j][2] = (i > 0 && j > 0) ? dp[i - 1][j - 1][2] + 1 : 1; // diagonal
dp[i][j][3] = (i > 0 && j < n - 1) ? dp[i - 1][j + 1][3] + 1 : 1; // anti-diagonal
maxLen = Math.max(maxLen, Math.max(Math.max(dp[i][j][0], dp[i][j][1]),
Math.max(dp[i][j][2], dp[i][j][3])));
}
}
}
return maxLen;
}
Explanation: Use 3D DP tracking consecutive ones in four directions ending at each cell. For each cell with 1, extend the count from the appropriate previous cell in each direction. Track maximum across all directions.
- Time Complexity: O(m * n) - visit each cell once
- Space Complexity: O(m * n) - 3D DP array
563. Binary Tree Tilt
Description: Given the root of a binary tree, return the sum of every tree node’s tilt. The tilt of a tree node is the absolute difference between the sum of all left subtree node values and all right subtree node values.
Java Solution:
public int findTilt(TreeNode root) {
int[] totalTilt = new int[1];
calculateSum(root, totalTilt);
return totalTilt[0];
}
private int calculateSum(TreeNode node, int[] totalTilt) {
if (node == null) return 0;
int leftSum = calculateSum(node.left, totalTilt);
int rightSum = calculateSum(node.right, totalTilt);
int tilt = Math.abs(leftSum - rightSum);
totalTilt[0] += tilt;
return leftSum + rightSum + node.val;
}
Explanation: Recursively calculate subtree sums. At each node, compute tilt as absolute difference of left and right subtree sums, add to total. Return sum of entire subtree including current node.
- Time Complexity: O(n) - visit each node once
- Space Complexity: O(h) - recursion stack depth
564. Find the Closest Palindrome
Description:
Given a string n representing an integer, return the closest integer (not including itself) which is a palindrome. If there is a tie, return the smaller one.
Java Solution:
public String nearestPalindromic(String n) {
long num = Long.parseLong(n);
int len = n.length();
Set<Long> candidates = new HashSet<>();
// Edge cases: 999...9 and 100...001
candidates.add((long) Math.pow(10, len) + 1);
candidates.add((long) Math.pow(10, len - 1) - 1);
// Get prefix and create palindrome
long prefix = Long.parseLong(n.substring(0, (len + 1) / 2));
for (long i = -1; i <= 1; i++) {
String palinPrefix = String.valueOf(prefix + i);
String palin = palinPrefix + new StringBuilder(palinPrefix).reverse()
.substring(len % 2);
candidates.add(Long.parseLong(palin));
}
candidates.remove(num);
long closest = -1;
for (long cand : candidates) {
if (closest == -1 ||
Math.abs(cand - num) < Math.abs(closest - num) ||
(Math.abs(cand - num) == Math.abs(closest - num) && cand < closest)) {
closest = cand;
}
}
return String.valueOf(closest);
}
Explanation: Generate candidates: mirror current prefix, mirror prefix±1, and edge cases (999…9, 100…001). Compare all candidates to find closest. Handle ties by choosing smaller value.
- Time Complexity: O(log n) - working with digits
- Space Complexity: O(1) - fixed number of candidates
565. Array Nesting
Description:
You are given an integer array nums of length n where nums is a permutation of [0, 1, …, n-1]. A set S[k] is defined by following nums[k] repeatedly. Return the length of the longest set S[k].
Java Solution:
public int arrayNesting(int[] nums) {
int maxLength = 0;
boolean[] visited = new boolean[nums.length];
for (int i = 0; i < nums.length; i++) {
if (!visited[i]) {
int length = 0;
int current = i;
while (!visited[current]) {
visited[current] = true;
current = nums[current];
length++;
}
maxLength = Math.max(maxLength, length);
}
}
return maxLength;
}
Explanation: Each element belongs to exactly one cycle. Use visited array to avoid recounting. For each unvisited element, follow the cycle until returning to start, counting length. Track maximum cycle length.
- Time Complexity: O(n) - each element visited once
- Space Complexity: O(n) - visited array
566. Reshape the Matrix
Description:
Given an m x n integer matrix mat and two integers r and c representing the number of rows and columns of the wanted reshaped matrix, reshape mat to r x c. If it’s impossible, return the original matrix.
Java Solution:
public int[][] matrixReshape(int[][] mat, int r, int c) {
int m = mat.length, n = mat[0].length;
if (m * n != r * c) return mat;
int[][] result = new int[r][c];
int row = 0, col = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
result[row][col] = mat[i][j];
col++;
if (col == c) {
col = 0;
row++;
}
}
}
return result;
}
Explanation: Check if reshape is possible (same total elements). Iterate through original matrix and fill new matrix sequentially. Track current position in result matrix, moving to next row when reaching column limit.
- Time Complexity: O(m * n) - process each element
- Space Complexity: O(r * c) - new matrix
567. Permutation in String
Description:
Given two strings s1 and s2, return true if s2 contains a permutation of s1. A permutation is a rearrangement of all characters.
Java Solution:
public boolean checkInclusion(String s1, String s2) {
if (s1.length() > s2.length()) return false;
int[] count = new int[26];
for (char c : s1.toCharArray()) {
count[c - 'a']++;
}
int left = 0, right = 0;
int required = s1.length();
while (right < s2.length()) {
// Expand window
if (count[s2.charAt(right) - 'a'] > 0) {
required--;
}
count[s2.charAt(right) - 'a']--;
right++;
// Check if permutation found
if (required == 0) return true;
// Shrink window when size exceeds s1 length
if (right - left == s1.length()) {
if (count[s2.charAt(left) - 'a'] >= 0) {
required++;
}
count[s2.charAt(left) - 'a']++;
left++;
}
}
return false;
}
Explanation: Use sliding window of size s1.length() on s2. Maintain character count difference. When window size matches s1, check if counts match (required == 0). Slide window by adding right and removing left characters.
- Time Complexity: O(n) - single pass with sliding window
- Space Complexity: O(1) - fixed 26 character array
568. Maximum Vacation Days
Description:
Given an n x n matrix flights representing flights and an n x k matrix days representing vacation days, return the maximum vacation days you can take. You start from city 0 and can take at most one flight per week.
Java Solution:
public int maxVacationDays(int[][] flights, int[][] days) {
int n = flights.length;
int k = days[0].length;
// dp[week][city] = max vacation days ending at city in week
int[][] dp = new int[k + 1][n];
for (int[] row : dp) {
Arrays.fill(row, Integer.MIN_VALUE);
}
dp[0][0] = 0;
for (int week = 0; week < k; week++) {
for (int src = 0; src < n; src++) {
if (dp[week][src] == Integer.MIN_VALUE) continue;
for (int dst = 0; dst < n; dst++) {
if (src == dst || flights[src][dst] == 1) {
dp[week + 1][dst] = Math.max(dp[week + 1][dst],
dp[week][src] + days[dst][week]);
}
}
}
}
int maxDays = 0;
for (int city = 0; city < n; city++) {
maxDays = Math.max(maxDays, dp[k][city]);
}
return maxDays;
}
Explanation: Use DP where dp[week][city] represents maximum vacation days when at city in given week. For each week and city, try flying to all reachable cities or staying. Add vacation days for destination city that week.
- Time Complexity: O(k * n^2) - weeks * cities * cities
- Space Complexity: O(k * n) - DP table
569. Median Employee Salary
Description: SQL problem - Write a query to find the median salary of each company. The median is the middle value in an ordered list. If there is an even number of values, the median is both middle values.
Java Solution:
// This is a SQL problem, but here's a Java solution for finding median in a list
public double findMedianSalary(List<Integer> salaries) {
Collections.sort(salaries);
int n = salaries.size();
if (n % 2 == 0) {
return (salaries.get(n / 2 - 1) + salaries.get(n / 2)) / 2.0;
} else {
return salaries.get(n / 2);
}
}
// For company groups
public Map<String, Double> findMedianByCompany(List<Employee> employees) {
Map<String, List<Integer>> companyToSalaries = new HashMap<>();
for (Employee emp : employees) {
companyToSalaries.computeIfAbsent(emp.company, k -> new ArrayList<>())
.add(emp.salary);
}
Map<String, Double> result = new HashMap<>();
for (Map.Entry<String, List<Integer>> entry : companyToSalaries.entrySet()) {
result.put(entry.getKey(), findMedianSalary(entry.getValue()));
}
return result;
}
class Employee {
String company;
int salary;
}
Explanation: Group employees by company, sort salaries for each company. For odd count, take middle element. For even count, average the two middle elements. Return median for each company.
- Time Complexity: O(n log n) - sorting salaries
- Space Complexity: O(n) - storing grouped salaries
570. Managers with at Least 5 Direct Reports
Description: SQL problem - Write a query to find managers with at least 5 direct reports. Return the manager name.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<String> findManagers(List<Employee> employees) {
Map<Integer, Integer> managerToReports = new HashMap<>();
Map<Integer, String> idToName = new HashMap<>();
for (Employee emp : employees) {
idToName.put(emp.id, emp.name);
if (emp.managerId != null) {
managerToReports.put(emp.managerId,
managerToReports.getOrDefault(emp.managerId, 0) + 1);
}
}
List<String> result = new ArrayList<>();
for (Map.Entry<Integer, Integer> entry : managerToReports.entrySet()) {
if (entry.getValue() >= 5) {
result.add(idToName.get(entry.getKey()));
}
}
return result;
}
class Employee {
int id;
String name;
Integer managerId;
}
Explanation: Count direct reports for each manager using a hashmap. Filter managers with count >= 5. Map manager IDs to names and return the list.
- Time Complexity: O(n) - single pass through employees
- Space Complexity: O(n) - hashmaps
571. Find Median Given Frequency of Numbers
Description: SQL problem - Given a table with numbers and their frequencies, find the median. The median is the middle value when all numbers are written out.
Java Solution:
public double findMedianWithFrequency(int[][] numFreq) {
// numFreq[i] = {number, frequency}
Arrays.sort(numFreq, (a, b) -> a[0] - b[0]);
int total = 0;
for (int[] pair : numFreq) {
total += pair[1];
}
int target1 = (total + 1) / 2;
int target2 = (total + 2) / 2;
int count = 0;
double median1 = 0, median2 = 0;
for (int[] pair : numFreq) {
count += pair[1];
if (count >= target1 && median1 == 0) {
median1 = pair[0];
}
if (count >= target2) {
median2 = pair[0];
break;
}
}
return (median1 + median2) / 2.0;
}
Explanation: Calculate total count, find positions of median elements. Accumulate frequencies until reaching median positions. For even total, average two middle values. For odd, return middle value.
- Time Complexity: O(n log n) - sorting, or O(n) if pre-sorted
- Space Complexity: O(1) - constant extra space
572. Subtree of Another Tree
Description:
Given the roots of two binary trees root and subRoot, return true if there is a subtree of root with the same structure and node values as subRoot.
Java Solution:
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
if (root == null) return false;
if (isSameTree(root, subRoot)) return true;
return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
}
private boolean isSameTree(TreeNode s, TreeNode t) {
if (s == null && t == null) return true;
if (s == null || t == null) return false;
if (s.val != t.val) return false;
return isSameTree(s.left, t.left) && isSameTree(s.right, t.right);
}
Explanation: For each node in main tree, check if subtree starting there matches subRoot. Use helper function to check if two trees are identical. Recursively check all nodes until match found or tree exhausted.
- Time Complexity: O(m * n) - m nodes in root, n nodes in subRoot
- Space Complexity: O(h) - recursion depth
573. Squirrel Simulation
Description:
There’s a squirrel on a tree at point tree, and nuts at various positions. The squirrel needs to collect all nuts and return them to the tree. Return the minimum distance.
Java Solution:
public int minDistance(int height, int width, int[] tree, int[] squirrel, int[][] nuts) {
int totalDistance = 0;
int maxSaving = Integer.MIN_VALUE;
for (int[] nut : nuts) {
int nutToTree = Math.abs(nut[0] - tree[0]) + Math.abs(nut[1] - tree[1]);
totalDistance += 2 * nutToTree; // Round trip from tree to nut
int squirrelToNut = Math.abs(nut[0] - squirrel[0]) + Math.abs(nut[1] - squirrel[1]);
int saving = nutToTree - squirrelToNut; // Saved by going to this nut first
maxSaving = Math.max(maxSaving, saving);
}
return totalDistance - maxSaving;
}
Explanation: Calculate total distance if starting from tree (2 * sum of all nut-to-tree distances). The squirrel should go to the nut that provides maximum saving (tree-to-nut minus squirrel-to-nut). Subtract this saving from total.
- Time Complexity: O(n) - iterate through all nuts
- Space Complexity: O(1) - constant space
574. Winning Candidate
Description: SQL problem - Write a query to find the candidate who won the election. The winner is the candidate with most votes.
Java Solution:
public String findWinner(List<Vote> votes) {
Map<String, Integer> voteCount = new HashMap<>();
for (Vote vote : votes) {
voteCount.put(vote.candidate, voteCount.getOrDefault(vote.candidate, 0) + 1);
}
String winner = "";
int maxVotes = 0;
for (Map.Entry<String, Integer> entry : voteCount.entrySet()) {
if (entry.getValue() > maxVotes) {
maxVotes = entry.getValue();
winner = entry.getKey();
}
}
return winner;
}
class Vote {
String candidate;
}
Explanation: Count votes for each candidate using hashmap. Find candidate with maximum vote count and return their name.
- Time Complexity: O(n) - count votes and find max
- Space Complexity: O(k) - k unique candidates
575. Distribute Candies
Description:
Alice has n candies where the i-th candy is of type candyType[i]. She can only eat n / 2 candies. Return the maximum number of different types of candies she can eat.
Java Solution:
public int distributeCandies(int[] candyType) {
Set<Integer> uniqueTypes = new HashSet<>();
for (int candy : candyType) {
uniqueTypes.add(candy);
}
return Math.min(uniqueTypes.size(), candyType.length / 2);
}
Explanation: Count unique candy types using a HashSet. Alice can eat at most n/2 candies, so the answer is the minimum of unique types and n/2. She gets maximum variety by eating different types until limit reached.
- Time Complexity: O(n) - iterate through all candies
- Space Complexity: O(n) - HashSet for unique types
576. Out of Boundary Paths
Description:
There is an m x n grid with a ball at position [startRow, startColumn]. The ball can move in four directions. Return the number of paths to move the ball out of the grid boundary within maxMove moves. Answer modulo 10^9 + 7.
Java Solution:
public int findPaths(int m, int n, int maxMove, int startRow, int startColumn) {
int MOD = 1000000007;
int[][][] dp = new int[maxMove + 1][m][n];
int[][] dirs = {{-1,0},{1,0},{0,-1},{0,1}};
for (int move = 1; move <= maxMove; move++) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
for (int[] dir : dirs) {
int ni = i + dir[0];
int nj = j + dir[1];
if (ni < 0 || ni >= m || nj < 0 || nj >= n) {
dp[move][i][j] = (dp[move][i][j] + 1) % MOD;
} else {
dp[move][i][j] = (dp[move][i][j] + dp[move - 1][ni][nj]) % MOD;
}
}
}
}
}
return dp[maxMove][startRow][startColumn];
}
Explanation: Use 3D DP where dp[move][i][j] represents number of ways to reach position (i,j) with exactly ‘move’ moves from start. For each position and move count, try all four directions. If next position is out of bounds, increment count.
- Time Complexity: O(maxMove * m * n) - all states
- Space Complexity: O(maxMove * m * n) - DP table
577. Employee Bonus
Description: SQL problem - Write a query to select employee name and bonus amount. Include employees with no bonus (show NULL).
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<EmployeeBonus> getEmployeeBonuses(List<Employee> employees,
List<Bonus> bonuses) {
Map<Integer, Integer> bonusMap = new HashMap<>();
for (Bonus bonus : bonuses) {
bonusMap.put(bonus.empId, bonus.bonus);
}
List<EmployeeBonus> result = new ArrayList<>();
for (Employee emp : employees) {
Integer bonus = bonusMap.get(emp.empId);
result.add(new EmployeeBonus(emp.name, bonus));
}
return result;
}
class Employee {
int empId;
String name;
}
class Bonus {
int empId;
int bonus;
}
class EmployeeBonus {
String name;
Integer bonus;
EmployeeBonus(String name, Integer bonus) {
this.name = name;
this.bonus = bonus;
}
}
Explanation: Create a map of employee ID to bonus amount. For each employee, look up their bonus in the map. If not found, bonus will be null. Return list of employee name and bonus pairs.
- Time Complexity: O(n + m) - n employees, m bonuses
- Space Complexity: O(m) - bonus map
578. Get Highest Answer Rate Question
Description: SQL problem - Find the question that has the highest answer rate. Answer rate = answers / shows.
Java Solution:
// This is a SQL problem, but here's a Java solution
public int getHighestAnswerRate(List<SurveyLog> logs) {
Map<Integer, int[]> questionStats = new HashMap<>();
for (SurveyLog log : logs) {
questionStats.putIfAbsent(log.questionId, new int[2]);
int[] stats = questionStats.get(log.questionId);
if ("show".equals(log.action)) {
stats[0]++;
} else if ("answer".equals(log.action)) {
stats[1]++;
}
}
int bestQuestion = -1;
double maxRate = 0;
for (Map.Entry<Integer, int[]> entry : questionStats.entrySet()) {
int shows = entry.getValue()[0];
int answers = entry.getValue()[1];
if (shows > 0) {
double rate = (double) answers / shows;
if (rate > maxRate || (rate == maxRate && entry.getKey() < bestQuestion)) {
maxRate = rate;
bestQuestion = entry.getKey();
}
}
}
return bestQuestion;
}
class SurveyLog {
int questionId;
String action;
}
Explanation: Track shows and answers for each question using a map. Calculate answer rate for each question. Return question ID with highest rate, breaking ties by smallest ID.
- Time Complexity: O(n) - process all logs
- Space Complexity: O(k) - k unique questions
579. Find Cumulative Salary of an Employee
Description: SQL problem - Calculate the cumulative sum of an employee’s salary over a period of 3 months, excluding the most recent month.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<EmployeeSalary> getCumulativeSalary(List<Salary> salaries) {
// Group by employee
Map<Integer, List<Salary>> empSalaries = new HashMap<>();
for (Salary s : salaries) {
empSalaries.computeIfAbsent(s.id, k -> new ArrayList<>()).add(s);
}
List<EmployeeSalary> result = new ArrayList<>();
for (Map.Entry<Integer, List<Salary>> entry : empSalaries.entrySet()) {
List<Salary> sals = entry.getValue();
Collections.sort(sals, (a, b) -> Integer.compare(a.month, b.month));
// Exclude most recent month
for (int i = 0; i < sals.size() - 1; i++) {
int cumulative = 0;
// Sum up to 3 months including current
for (int j = Math.max(0, i - 2); j <= i; j++) {
cumulative += sals.get(j).salary;
}
result.add(new EmployeeSalary(entry.getKey(), sals.get(i).month, cumulative));
}
}
return result;
}
class Salary {
int id;
int month;
int salary;
}
class EmployeeSalary {
int id;
int month;
int cumulative;
EmployeeSalary(int id, int month, int cumulative) {
this.id = id;
this.month = month;
this.cumulative = cumulative;
}
}
Explanation: Group salaries by employee, sort by month. For each month except the most recent, calculate cumulative sum of up to 3 months ending at that month.
- Time Complexity: O(n log n) - sorting
- Space Complexity: O(n) - grouping salaries
580. Count Student Number in Departments
Description: SQL problem - Count the number of students in each department. Include departments with zero students.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<DepartmentCount> countStudents(List<Department> departments,
List<Student> students) {
Map<Integer, Integer> deptCount = new HashMap<>();
// Initialize all departments with 0
for (Department dept : departments) {
deptCount.put(dept.deptId, 0);
}
// Count students per department
for (Student student : students) {
if (student.deptId != null && deptCount.containsKey(student.deptId)) {
deptCount.put(student.deptId, deptCount.get(student.deptId) + 1);
}
}
List<DepartmentCount> result = new ArrayList<>();
for (Department dept : departments) {
result.add(new DepartmentCount(dept.deptName,
deptCount.get(dept.deptId)));
}
return result;
}
class Department {
int deptId;
String deptName;
}
class Student {
Integer deptId;
}
class DepartmentCount {
String deptName;
int studentCount;
DepartmentCount(String deptName, int studentCount) {
this.deptName = deptName;
this.studentCount = studentCount;
}
}
Explanation: Initialize count map with all departments set to 0. Count students for each department. Return list of department names with their student counts, including departments with zero students.
- Time Complexity: O(n + m) - n departments, m students
- Space Complexity: O(n) - count map
581. Shortest Unsorted Continuous Subarray
Description:
Given an integer array nums, find the length of the shortest continuous subarray such that if you sort only this subarray, the whole array will be sorted.
Java Solution:
public int findUnsortedSubarray(int[] nums) {
int n = nums.length;
int left = 0, right = n - 1;
// Find left boundary - first element out of order
while (left < n - 1 && nums[left] <= nums[left + 1]) {
left++;
}
if (left == n - 1) return 0; // Already sorted
// Find right boundary - last element out of order
while (right > 0 && nums[right] >= nums[right - 1]) {
right--;
}
// Find min and max in the middle section
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
for (int i = left; i <= right; i++) {
min = Math.min(min, nums[i]);
max = Math.max(max, nums[i]);
}
// Expand left boundary if needed
while (left > 0 && nums[left - 1] > min) {
left--;
}
// Expand right boundary if needed
while (right < n - 1 && nums[right + 1] < max) {
right++;
}
return right - left + 1;
}
Explanation: Find initial boundaries where array becomes unsorted. Find min and max in that range. Expand boundaries if elements outside range are greater than min or less than max, since they need to be included in the sort.
- Time Complexity: O(n) - linear scan
- Space Complexity: O(1) - constant space
582. Kill Process
Description:
Given n processes with PIDs and PPIDs (parent process IDs), and a process to kill, return list of PIDs that will be killed including all descendants.
Java Solution:
public List<Integer> killProcess(List<Integer> pid, List<Integer> ppid, int kill) {
Map<Integer, List<Integer>> children = new HashMap<>();
// Build parent-child relationships
for (int i = 0; i < ppid.size(); i++) {
int parent = ppid.get(i);
int child = pid.get(i);
children.computeIfAbsent(parent, k -> new ArrayList<>()).add(child);
}
List<Integer> killed = new ArrayList<>();
Queue<Integer> queue = new LinkedList<>();
queue.offer(kill);
while (!queue.isEmpty()) {
int current = queue.poll();
killed.add(current);
if (children.containsKey(current)) {
for (int child : children.get(current)) {
queue.offer(child);
}
}
}
return killed;
}
Explanation: Build a map of parent to children processes. Use BFS starting from the killed process to find all descendants. Add each process and its children to the result list.
- Time Complexity: O(n) - visit each process once
- Space Complexity: O(n) - map and queue
583. Delete Operation for Two Strings
Description:
Given two strings word1 and word2, return the minimum number of steps required to make them the same, where in each step you can delete one character from either string.
Java Solution:
public int minDistance(String word1, String word2) {
int m = word1.length(), n = word2.length();
int[][] dp = new int[m + 1][n + 1];
// Initialize base cases
for (int i = 0; i <= m; i++) {
dp[i][0] = i;
}
for (int j = 0; j <= n; j++) {
dp[0][j] = j;
}
// Fill DP table
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + 1;
}
}
}
return dp[m][n];
}
Explanation: Use DP where dp[i][j] represents minimum deletions to make word1[0..i-1] equal to word2[0..j-1]. If characters match, no deletion needed. Otherwise, try deleting from either string and take minimum.
- Time Complexity: O(m * n) - fill DP table
- Space Complexity: O(m * n) - DP table
584. Find Customer Referee
Description: SQL problem - Write a query to find names of customers who were not referred by customer with ID = 2.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<String> findCustomers(List<Customer> customers) {
List<String> result = new ArrayList<>();
for (Customer customer : customers) {
if (customer.refereeId == null || customer.refereeId != 2) {
result.add(customer.name);
}
}
return result;
}
class Customer {
int id;
String name;
Integer refereeId;
}
Explanation: Filter customers where referee ID is either null or not equal to 2. Return list of customer names matching this condition.
- Time Complexity: O(n) - iterate through all customers
- Space Complexity: O(k) - k matching customers
585. Investments in 2016
Description: SQL problem - Find the sum of all total investment values in 2016 for policyholders who meet criteria: same TIV_2015 as another policyholder, and unique location.
Java Solution:
// This is a SQL problem, but here's a Java solution
public double findInvestment(List<Insurance> policies) {
Map<Double, Integer> tiv2015Count = new HashMap<>();
Map<String, Integer> locationCount = new HashMap<>();
// Count TIV_2015 and locations
for (Insurance p : policies) {
tiv2015Count.put(p.tiv2015, tiv2015Count.getOrDefault(p.tiv2015, 0) + 1);
String loc = p.lat + "," + p.lon;
locationCount.put(loc, locationCount.getOrDefault(loc, 0) + 1);
}
double sum = 0;
for (Insurance p : policies) {
String loc = p.lat + "," + p.lon;
if (tiv2015Count.get(p.tiv2015) > 1 && locationCount.get(loc) == 1) {
sum += p.tiv2016;
}
}
return sum;
}
class Insurance {
double tiv2015;
double tiv2016;
double lat;
double lon;
}
Explanation: Count occurrences of each TIV_2015 value and each location. For policies with duplicate TIV_2015 but unique location, sum their TIV_2016 values.
- Time Complexity: O(n) - two passes through policies
- Space Complexity: O(n) - hashmaps
586. Customer Placing the Largest Number of Orders
Description: SQL problem - Find the customer who has placed the largest number of orders. It’s guaranteed there is only one customer.
Java Solution:
// This is a SQL problem, but here's a Java solution
public int findTopCustomer(List<Order> orders) {
Map<Integer, Integer> customerOrders = new HashMap<>();
for (Order order : orders) {
customerOrders.put(order.customerId,
customerOrders.getOrDefault(order.customerId, 0) + 1);
}
int topCustomer = -1;
int maxOrders = 0;
for (Map.Entry<Integer, Integer> entry : customerOrders.entrySet()) {
if (entry.getValue() > maxOrders) {
maxOrders = entry.getValue();
topCustomer = entry.getKey();
}
}
return topCustomer;
}
class Order {
int customerId;
}
Explanation: Count orders per customer using a hashmap. Find customer with maximum order count and return their ID.
- Time Complexity: O(n) - process all orders
- Space Complexity: O(k) - k unique customers
587. Erect the Fence
Description: Given an array of points representing positions of trees, return the fence that encloses all trees using minimum rope. This is the convex hull problem.
Java Solution:
public int[][] outerTrees(int[][] trees) {
Arrays.sort(trees, (a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
List<int[]> hull = new ArrayList<>();
// Build lower hull
for (int[] tree : trees) {
while (hull.size() >= 2 && cross(hull.get(hull.size() - 2),
hull.get(hull.size() - 1), tree) < 0) {
hull.remove(hull.size() - 1);
}
hull.add(tree);
}
// Build upper hull
int lowerSize = hull.size();
for (int i = trees.length - 2; i >= 0; i--) {
while (hull.size() > lowerSize && cross(hull.get(hull.size() - 2),
hull.get(hull.size() - 1),
trees[i]) < 0) {
hull.remove(hull.size() - 1);
}
hull.add(trees[i]);
}
hull.remove(hull.size() - 1); // Remove duplicate point
// Remove duplicates
Set<String> seen = new HashSet<>();
List<int[]> result = new ArrayList<>();
for (int[] point : hull) {
String key = point[0] + "," + point[1];
if (seen.add(key)) {
result.add(point);
}
}
return result.toArray(new int[result.size()][]);
}
private int cross(int[] p, int[] q, int[] r) {
return (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1]);
}
Explanation: Use Graham scan algorithm to find convex hull. Sort points by x-coordinate. Build lower and upper hulls by checking cross product to ensure counter-clockwise turns. Remove collinear duplicates.
- Time Complexity: O(n log n) - sorting dominates
- Space Complexity: O(n) - hull storage
588. Design In-Memory File System
Description: Design a file system that supports creating directories, listing files, adding content to files, and reading file content.
Java Solution:
class FileSystem {
class Node {
boolean isFile = false;
Map<String, Node> children = new HashMap<>();
StringBuilder content = new StringBuilder();
}
Node root;
public FileSystem() {
root = new Node();
}
public List<String> ls(String path) {
Node node = getNode(path);
List<String> result = new ArrayList<>();
if (node.isFile) {
String[] parts = path.split("/");
result.add(parts[parts.length - 1]);
} else {
result.addAll(node.children.keySet());
Collections.sort(result);
}
return result;
}
public void mkdir(String path) {
getNode(path);
}
public void addContentToFile(String filePath, String content) {
Node node = getNode(filePath);
node.isFile = true;
node.content.append(content);
}
public String readContentFromFile(String filePath) {
Node node = getNode(filePath);
return node.content.toString();
}
private Node getNode(String path) {
String[] parts = path.split("/");
Node node = root;
for (String part : parts) {
if (part.isEmpty()) continue;
node.children.putIfAbsent(part, new Node());
node = node.children.get(part);
}
return node;
}
}
Explanation: Use a trie-like structure where each node represents a file or directory. Each node has a map of children and optional content for files. Navigate path by splitting on ”/” and creating nodes as needed.
- Time Complexity: O(m) for all operations - m is path length
- Space Complexity: O(n * m) - n nodes, m average path length
589. N-ary Tree Preorder Traversal
Description: Given the root of an n-ary tree, return the preorder traversal of its nodes’ values.
Java Solution:
class Node {
public int val;
public List<Node> children;
}
public List<Integer> preorder(Node root) {
List<Integer> result = new ArrayList<>();
if (root == null) return result;
Stack<Node> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
Node node = stack.pop();
result.add(node.val);
// Add children in reverse order
for (int i = node.children.size() - 1; i >= 0; i--) {
stack.push(node.children.get(i));
}
}
return result;
}
// Recursive solution
public List<Integer> preorderRecursive(Node root) {
List<Integer> result = new ArrayList<>();
helper(root, result);
return result;
}
private void helper(Node node, List<Integer> result) {
if (node == null) return;
result.add(node.val);
for (Node child : node.children) {
helper(child, result);
}
}
Explanation: Preorder traversal visits root, then children left to right. Iterative approach uses stack, adding children in reverse order. Recursive approach directly implements the definition.
- Time Complexity: O(n) - visit each node once
- Space Complexity: O(n) - stack/recursion depth
590. N-ary Tree Postorder Traversal
Description: Given the root of an n-ary tree, return the postorder traversal of its nodes’ values.
Java Solution:
class Node {
public int val;
public List<Node> children;
}
public List<Integer> postorder(Node root) {
LinkedList<Integer> result = new LinkedList<>();
if (root == null) return result;
Stack<Node> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
Node node = stack.pop();
result.addFirst(node.val); // Add to front
// Add children in normal order
for (Node child : node.children) {
stack.push(child);
}
}
return result;
}
// Recursive solution
public List<Integer> postorderRecursive(Node root) {
List<Integer> result = new ArrayList<>();
helper(root, result);
return result;
}
private void helper(Node node, List<Integer> result) {
if (node == null) return;
for (Node child : node.children) {
helper(child, result);
}
result.add(node.val);
}
Explanation: Postorder traversal visits all children first, then root. Iterative approach reverses preorder by adding to front of list. Recursive approach processes all children before adding current node value.
- Time Complexity: O(n) - visit each node once
- Space Complexity: O(n) - stack/recursion depth
591. Tag Validator
Description: Given a string representing a code snippet, check whether it is valid. The code must be wrapped in a valid closed tag, and tags must be properly nested with valid tag names.
Java Solution:
public boolean isValid(String code) {
if (code.charAt(0) != '<' || code.charAt(code.length() - 1) != '>') {
return false;
}
Stack<String> stack = new Stack<>();
int i = 0;
while (i < code.length()) {
if (i > 0 && stack.isEmpty()) return false; // Content after closing root tag
if (code.charAt(i) == '<') {
if (i == code.length() - 1) return false;
// CDATA
if (code.charAt(i + 1) == '!') {
if (stack.isEmpty()) return false;
int cdataEnd = code.indexOf("]]>", i);
if (cdataEnd == -1 || !code.substring(i, i + 9).equals("<![CDATA[")) {
return false;
}
i = cdataEnd + 3;
}
// Closing tag
else if (code.charAt(i + 1) == '/') {
int closeEnd = code.indexOf('>', i);
if (closeEnd == -1) return false;
String tagName = code.substring(i + 2, closeEnd);
if (!isValidTagName(tagName) || stack.isEmpty() ||
!stack.pop().equals(tagName)) {
return false;
}
i = closeEnd + 1;
}
// Opening tag
else {
int closeEnd = code.indexOf('>', i);
if (closeEnd == -1) return false;
String tagName = code.substring(i + 1, closeEnd);
if (!isValidTagName(tagName)) return false;
stack.push(tagName);
i = closeEnd + 1;
}
} else {
i++;
}
}
return stack.isEmpty();
}
private boolean isValidTagName(String name) {
if (name.length() < 1 || name.length() > 9) return false;
for (char c : name.toCharArray()) {
if (!Character.isUpperCase(c)) return false;
}
return true;
}
Explanation: Parse the code string character by character. Use stack to track open tags. Handle three cases: CDATA sections, closing tags, and opening tags. Validate tag names are 1-9 uppercase letters. Ensure all tags are properly closed.
- Time Complexity: O(n) - single pass through string
- Space Complexity: O(n) - stack for nested tags
592. Fraction Addition and Subtraction
Description: Given a string expression representing an expression of fraction addition and subtraction, return the result in string format in irreducible fraction form.
Java Solution:
public String fractionAddition(String expression) {
int numerator = 0, denominator = 1;
int i = 0;
while (i < expression.length()) {
int sign = 1;
if (expression.charAt(i) == '+' || expression.charAt(i) == '-') {
sign = expression.charAt(i) == '+' ? 1 : -1;
i++;
}
int num = 0;
while (i < expression.length() && Character.isDigit(expression.charAt(i))) {
num = num * 10 + (expression.charAt(i) - '0');
i++;
}
num *= sign;
i++; // Skip '/'
int den = 0;
while (i < expression.length() && Character.isDigit(expression.charAt(i))) {
den = den * 10 + (expression.charAt(i) - '0');
i++;
}
// Add fractions: a/b + c/d = (a*d + c*b) / (b*d)
numerator = numerator * den + num * denominator;
denominator *= den;
// Reduce
int gcd = gcd(Math.abs(numerator), denominator);
numerator /= gcd;
denominator /= gcd;
}
return numerator + "/" + denominator;
}
private int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
Explanation: Parse fractions one by one. For each fraction, add to running total using common denominator. After each addition, reduce fraction using GCD. Continue until all fractions processed.
- Time Complexity: O(n log k) - n is length, log k for GCD
- Space Complexity: O(1) - constant space
593. Valid Square
Description: Given the coordinates of four points in 2D space, return whether they form a square.
Java Solution:
public boolean validSquare(int[] p1, int[] p2, int[] p3, int[] p4) {
int[][] points = {p1, p2, p3, p4};
int[] distances = new int[6];
int index = 0;
// Calculate all 6 distances
for (int i = 0; i < 4; i++) {
for (int j = i + 1; j < 4; j++) {
distances[index++] = distanceSquared(points[i], points[j]);
}
}
Arrays.sort(distances);
// Valid square has 4 equal sides and 2 equal diagonals
// Diagonals are longer than sides
return distances[0] > 0 &&
distances[0] == distances[1] &&
distances[1] == distances[2] &&
distances[2] == distances[3] &&
distances[4] == distances[5] &&
distances[3] * 2 == distances[4];
}
private int distanceSquared(int[] p1, int[] p2) {
int dx = p1[0] - p2[0];
int dy = p1[1] - p2[1];
return dx * dx + dy * dy;
}
Explanation: Calculate all 6 pairwise distances. Sort them. A valid square has 4 equal shorter distances (sides) and 2 equal longer distances (diagonals). Diagonal length should be sqrt(2) times side length, or diagonal^2 = 2 * side^2.
- Time Complexity: O(1) - fixed number of points
- Space Complexity: O(1) - constant space
594. Longest Harmonious Subsequence
Description: A harmonious array is one where the difference between its maximum and minimum value is exactly 1. Given an array, find the length of its longest harmonious subsequence.
Java Solution:
public int findLHS(int[] nums) {
Map<Integer, Integer> count = new HashMap<>();
for (int num : nums) {
count.put(num, count.getOrDefault(num, 0) + 1);
}
int maxLen = 0;
for (int num : count.keySet()) {
if (count.containsKey(num + 1)) {
maxLen = Math.max(maxLen, count.get(num) + count.get(num + 1));
}
}
return maxLen;
}
Explanation: Count frequency of each number using hashmap. For each number, check if number+1 exists. If so, their combined count forms a harmonious subsequence. Track maximum length.
- Time Complexity: O(n) - count frequencies and check pairs
- Space Complexity: O(n) - frequency map
595. Big Countries
Description: SQL problem - Find countries that are big (area >= 3 million sq km or population >= 25 million). Return name, population, and area.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<Country> findBigCountries(List<Country> countries) {
List<Country> result = new ArrayList<>();
for (Country country : countries) {
if (country.area >= 3000000 || country.population >= 25000000) {
result.add(country);
}
}
return result;
}
class Country {
String name;
int population;
int area;
}
Explanation: Filter countries where area is at least 3 million or population is at least 25 million. Return list of countries meeting either criterion.
- Time Complexity: O(n) - iterate through all countries
- Space Complexity: O(k) - k big countries
596. Classes More Than 5 Students
Description: SQL problem - Find all classes that have at least 5 students. Return class names.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<String> findPopularClasses(List<Course> courses) {
Map<String, Integer> classCount = new HashMap<>();
for (Course course : courses) {
classCount.put(course.className,
classCount.getOrDefault(course.className, 0) + 1);
}
List<String> result = new ArrayList<>();
for (Map.Entry<String, Integer> entry : classCount.entrySet()) {
if (entry.getValue() >= 5) {
result.add(entry.getKey());
}
}
return result;
}
class Course {
String student;
String className;
}
Explanation: Count students per class using hashmap. Filter classes with at least 5 students and return their names.
- Time Complexity: O(n) - process all course enrollments
- Space Complexity: O(k) - k unique classes
597. Friend Requests I: Overall Acceptance Rate
Description: SQL problem - Calculate the overall acceptance rate of friend requests. Rate = accepted requests / total requests.
Java Solution:
// This is a SQL problem, but here's a Java solution
public double findAcceptanceRate(List<Request> requests,
List<Accepted> accepted) {
// Use set to count unique requests
Set<String> uniqueRequests = new HashSet<>();
for (Request req : requests) {
uniqueRequests.add(req.senderId + "-" + req.receiverId);
}
Set<String> uniqueAccepted = new HashSet<>();
for (Accepted acc : accepted) {
uniqueAccepted.add(acc.senderId + "-" + acc.receiverId);
}
if (uniqueRequests.isEmpty()) return 0.0;
return (double) uniqueAccepted.size() / uniqueRequests.size();
}
class Request {
int senderId;
int receiverId;
}
class Accepted {
int senderId;
int receiverId;
}
Explanation: Count unique friend requests and unique accepted requests. Calculate acceptance rate as accepted / total. Handle edge case of no requests.
- Time Complexity: O(n + m) - n requests, m accepted
- Space Complexity: O(n + m) - sets for uniqueness
598. Range Addition II
Description: Given an m x n matrix initialized with all 0s and several update operations where each operation adds 1 to all elements in a submatrix from (0,0) to (ai, bi), return the count of maximum integers in the matrix after all operations.
Java Solution:
public int maxCount(int m, int n, int[][] ops) {
int minRow = m;
int minCol = n;
for (int[] op : ops) {
minRow = Math.min(minRow, op[0]);
minCol = Math.min(minCol, op[1]);
}
return minRow * minCol;
}
Explanation: The maximum value will be in the intersection of all operation ranges, which is the smallest rectangle. Find minimum row and column across all operations - that gives the area with maximum increments.
- Time Complexity: O(k) - k operations
- Space Complexity: O(1) - constant space
599. Minimum Index Sum of Two Lists
Description: Given two arrays of strings representing restaurant lists, find the common restaurants with the least list index sum. If there are multiple answers, return them all.
Java Solution:
public String[] findRestaurant(String[] list1, String[] list2) {
Map<String, Integer> indexMap = new HashMap<>();
for (int i = 0; i < list1.length; i++) {
indexMap.put(list1[i], i);
}
List<String> result = new ArrayList<>();
int minSum = Integer.MAX_VALUE;
for (int j = 0; j < list2.length; j++) {
if (indexMap.containsKey(list2[j])) {
int sum = j + indexMap.get(list2[j]);
if (sum < minSum) {
minSum = sum;
result.clear();
result.add(list2[j]);
} else if (sum == minSum) {
result.add(list2[j]);
}
}
}
return result.toArray(new String[0]);
}
Explanation: Build hashmap of restaurant names to indices from list1. For each restaurant in list2, if it exists in list1, calculate index sum. Track minimum sum and collect all restaurants with that sum.
- Time Complexity: O(n + m) - n + m total restaurants
- Space Complexity: O(n) - hashmap for list1
600. Non-negative Integers without Consecutive Ones
Description:
Given a positive integer n, return the number of non-negative integers less than or equal to n whose binary representations do not contain consecutive ones.
Java Solution:
public int findIntegers(int n) {
String binary = Integer.toBinaryString(n);
int len = binary.length();
// fib[i] = count of valid i-bit numbers
int[] fib = new int[len + 1];
fib[0] = 1;
fib[1] = 2;
for (int i = 2; i <= len; i++) {
fib[i] = fib[i - 1] + fib[i - 2];
}
int result = 0;
int prevBit = 0;
for (int i = 0; i < len; i++) {
if (binary.charAt(i) == '1') {
result += fib[len - i - 1];
if (prevBit == 1) {
result--;
break;
}
prevBit = 1;
} else {
prevBit = 0;
}
}
return result + 1;
}
Explanation: Use Fibonacci-based DP. For each bit position in n, if it’s 1, add count of all valid numbers with 0 at that position. If we encounter consecutive 1s in n itself, stop counting. The pattern follows Fibonacci sequence.
- Time Complexity: O(log n) - number of bits
- Space Complexity: O(log n) - Fibonacci array
601. Human Traffic of Stadium
Description: SQL problem - Find all stadium records with high traffic (people >= 100) where there are at least 3 consecutive rows with high traffic.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<Stadium> findHighTraffic(List<Stadium> records) {
List<Stadium> result = new ArrayList<>();
if (records.size() < 3) return result;
for (int i = 0; i < records.size(); i++) {
boolean isValid = false;
// Check if part of consecutive 3
if (i >= 2 && records.get(i).people >= 100 &&
records.get(i - 1).people >= 100 &&
records.get(i - 2).people >= 100 &&
records.get(i).id == records.get(i - 1).id + 1 &&
records.get(i - 1).id == records.get(i - 2).id + 1) {
isValid = true;
}
// Check if part of consecutive 3 (middle)
if (i >= 1 && i < records.size() - 1 &&
records.get(i).people >= 100 &&
records.get(i - 1).people >= 100 &&
records.get(i + 1).people >= 100 &&
records.get(i).id == records.get(i - 1).id + 1 &&
records.get(i + 1).id == records.get(i).id + 1) {
isValid = true;
}
// Check if part of consecutive 3 (first)
if (i < records.size() - 2 &&
records.get(i).people >= 100 &&
records.get(i + 1).people >= 100 &&
records.get(i + 2).people >= 100 &&
records.get(i + 1).id == records.get(i).id + 1 &&
records.get(i + 2).id == records.get(i + 1).id + 1) {
isValid = true;
}
if (isValid && !result.contains(records.get(i))) {
result.add(records.get(i));
}
}
return result;
}
class Stadium {
int id;
int people;
}
Explanation: For each record, check if it’s part of any consecutive sequence of 3+ records with people >= 100. Check all positions (first, middle, last) in potential sequences.
- Time Complexity: O(n) - check each record
- Space Complexity: O(k) - k valid records
602. Friend Requests II: Who Has the Most Friends
Description: SQL problem - Find the person who has the most friends and the number of friends. The friend relationship is bidirectional.
Java Solution:
// This is a SQL problem, but here's a Java solution
public PersonFriends findMostFriends(List<Request> requests) {
Map<Integer, Set<Integer>> friendMap = new HashMap<>();
for (Request req : requests) {
friendMap.computeIfAbsent(req.requester, k -> new HashSet<>())
.add(req.accepter);
friendMap.computeIfAbsent(req.accepter, k -> new HashSet<>())
.add(req.requester);
}
int maxFriends = 0;
int personId = -1;
for (Map.Entry<Integer, Set<Integer>> entry : friendMap.entrySet()) {
if (entry.getValue().size() > maxFriends) {
maxFriends = entry.getValue().size();
personId = entry.getKey();
}
}
return new PersonFriends(personId, maxFriends);
}
class Request {
int requester;
int accepter;
}
class PersonFriends {
int id;
int numFriends;
PersonFriends(int id, int numFriends) {
this.id = id;
this.numFriends = numFriends;
}
}
Explanation: Build bidirectional friend graph using map of sets. For each accepted request, add both persons as friends of each other. Find person with maximum number of unique friends.
- Time Complexity: O(n) - process all requests
- Space Complexity: O(n) - friend map
603. Consecutive Available Seats
Description: SQL problem - Find all consecutive available seats in a cinema. Return seat IDs in ascending order.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<Integer> findConsecutiveSeats(List<Cinema> seats) {
Collections.sort(seats, (a, b) -> a.seatId - b.seatId);
Set<Integer> consecutive = new HashSet<>();
for (int i = 0; i < seats.size() - 1; i++) {
if (seats.get(i).free && seats.get(i + 1).free &&
seats.get(i + 1).seatId == seats.get(i).seatId + 1) {
consecutive.add(seats.get(i).seatId);
consecutive.add(seats.get(i + 1).seatId);
}
}
List<Integer> result = new ArrayList<>(consecutive);
Collections.sort(result);
return result;
}
class Cinema {
int seatId;
boolean free;
}
Explanation: Sort seats by ID. Check each pair of adjacent seats - if both are free and consecutive, add both to result set. Return sorted list of seat IDs.
- Time Complexity: O(n log n) - sorting
- Space Complexity: O(n) - result set
604. Design Compressed String Iterator
Description: Design an iterator that supports iterating through a compressed string in the form “a3b2c1” which represents “aaabbc”.
Java Solution:
class StringIterator {
private String compressedString;
private int index;
private char currentChar;
private int currentCount;
public StringIterator(String compressedString) {
this.compressedString = compressedString;
this.index = 0;
loadNext();
}
private void loadNext() {
if (index >= compressedString.length()) {
currentCount = 0;
return;
}
currentChar = compressedString.charAt(index++);
int count = 0;
while (index < compressedString.length() &&
Character.isDigit(compressedString.charAt(index))) {
count = count * 10 + (compressedString.charAt(index) - '0');
index++;
}
currentCount = count;
}
public char next() {
if (!hasNext()) return ' ';
char result = currentChar;
currentCount--;
if (currentCount == 0) {
loadNext();
}
return result;
}
public boolean hasNext() {
return currentCount > 0;
}
}
Explanation: Parse compressed string by tracking current character and its remaining count. When calling next(), return current character and decrement count. When count reaches 0, load next character and its count.
- Time Complexity: O(1) for next and hasNext
- Space Complexity: O(1) - constant state variables
605. Can Place Flowers
Description:
You have a long flowerbed where some plots are planted and some are not. Flowers cannot be planted in adjacent plots. Given an array flowerbed and integer n, return if n new flowers can be planted without violating the no-adjacent rule.
Java Solution:
public boolean canPlaceFlowers(int[] flowerbed, int n) {
int count = 0;
for (int i = 0; i < flowerbed.length; i++) {
if (flowerbed[i] == 0) {
boolean leftEmpty = (i == 0) || (flowerbed[i - 1] == 0);
boolean rightEmpty = (i == flowerbed.length - 1) || (flowerbed[i + 1] == 0);
if (leftEmpty && rightEmpty) {
flowerbed[i] = 1;
count++;
}
}
}
return count >= n;
}
Explanation: Iterate through flowerbed. For each empty plot, check if both adjacent plots are empty (handling edges). If so, plant a flower there and increment count. Return whether we planted at least n flowers.
- Time Complexity: O(m) - m is flowerbed length
- Space Complexity: O(1) - in-place modification
606. Construct String from Binary Tree
Description: Construct a string from a binary tree using preorder traversal. Omit all empty parentheses pairs that don’t affect the one-to-one mapping relationship between the string and the tree.
Java Solution:
public String tree2str(TreeNode root) {
if (root == null) return "";
StringBuilder sb = new StringBuilder();
sb.append(root.val);
if (root.left != null || root.right != null) {
sb.append("(").append(tree2str(root.left)).append(")");
if (root.right != null) {
sb.append("(").append(tree2str(root.right)).append(")");
}
}
return sb.toString();
}
Explanation: Recursively build string in preorder. Always include left subtree if either child exists (even if left is null). Only include right subtree parentheses if right child exists. This ensures unique reconstruction.
- Time Complexity: O(n) - visit each node once
- Space Complexity: O(h) - recursion depth
607. Sales Person
Description: SQL problem - Find names of sales persons who have no orders related to company “RED”.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<String> findSalesPerson(List<SalesPerson> salesPeople,
List<Order> orders,
List<Company> companies) {
// Find company RED's ID
int redId = -1;
for (Company company : companies) {
if ("RED".equals(company.name)) {
redId = company.comId;
break;
}
}
// Find sales IDs who sold to RED
Set<Integer> soldToRed = new HashSet<>();
for (Order order : orders) {
if (order.comId == redId) {
soldToRed.add(order.salesId);
}
}
// Return sales people who didn't sell to RED
List<String> result = new ArrayList<>();
for (SalesPerson sp : salesPeople) {
if (!soldToRed.contains(sp.salesId)) {
result.add(sp.name);
}
}
return result;
}
class SalesPerson {
int salesId;
String name;
}
class Company {
int comId;
String name;
}
class Order {
int salesId;
int comId;
}
Explanation: Find company RED’s ID. Collect all sales IDs who have orders with RED. Return names of sales people not in that set.
- Time Complexity: O(n + m + k) - people, orders, companies
- Space Complexity: O(m) - set of sales IDs
608. Tree Node
Description: SQL problem - For each node in a tree table, identify whether it’s a Root, Inner node, or Leaf.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<NodeType> classifyNodes(List<Tree> nodes) {
Set<Integer> parents = new HashSet<>();
for (Tree node : nodes) {
if (node.pId != null) {
parents.add(node.pId);
}
}
List<NodeType> result = new ArrayList<>();
for (Tree node : nodes) {
String type;
if (node.pId == null) {
type = "Root";
} else if (parents.contains(node.id)) {
type = "Inner";
} else {
type = "Leaf";
}
result.add(new NodeType(node.id, type));
}
return result;
}
class Tree {
int id;
Integer pId;
}
class NodeType {
int id;
String type;
NodeType(int id, String type) {
this.id = id;
this.type = type;
}
}
Explanation: Collect all parent IDs. For each node: if no parent, it’s Root; if it’s a parent of others, it’s Inner; otherwise it’s Leaf.
- Time Complexity: O(n) - two passes through nodes
- Space Complexity: O(n) - parent set
609. Find Duplicate File in System
Description: Given a list of directory paths with files and their content, group files by identical content. Return groups where each group has at least 2 files with same content.
Java Solution:
public List<List<String>> findDuplicate(String[] paths) {
Map<String, List<String>> contentToFiles = new HashMap<>();
for (String path : paths) {
String[] parts = path.split(" ");
String directory = parts[0];
for (int i = 1; i < parts.length; i++) {
int idx = parts[i].indexOf('(');
String filename = parts[i].substring(0, idx);
String content = parts[i].substring(idx + 1, parts[i].length() - 1);
String fullPath = directory + "/" + filename;
contentToFiles.computeIfAbsent(content, k -> new ArrayList<>())
.add(fullPath);
}
}
List<List<String>> result = new ArrayList<>();
for (List<String> files : contentToFiles.values()) {
if (files.size() > 1) {
result.add(files);
}
}
return result;
}
Explanation: Parse each directory entry to extract file paths and contents. Group files by content using hashmap. Return groups with more than one file.
- Time Complexity: O(n * m) - n paths, m average files per path
- Space Complexity: O(n * m) - storing all file paths
610. Triangle Judgement
Description: SQL problem - Given a table with three sides of a triangle (x, y, z), determine if they can form a valid triangle. Triangle inequality: sum of any two sides > third side.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<TriangleResult> judgeTriangle(List<Triangle> triangles) {
List<TriangleResult> result = new ArrayList<>();
for (Triangle t : triangles) {
boolean isValid = (t.x + t.y > t.z) &&
(t.x + t.z > t.y) &&
(t.y + t.z > t.x);
result.add(new TriangleResult(t.x, t.y, t.z,
isValid ? "Yes" : "No"));
}
return result;
}
class Triangle {
int x;
int y;
int z;
}
class TriangleResult {
int x;
int y;
int z;
String valid;
TriangleResult(int x, int y, int z, String valid) {
this.x = x;
this.y = y;
this.z = z;
this.valid = valid;
}
}
Explanation: For each triangle, check if it satisfies triangle inequality: sum of any two sides must be greater than the third side. All three conditions must be true.
- Time Complexity: O(n) - check each triangle
- Space Complexity: O(n) - result list
611. Valid Triangle Number
Description:
Given an integer array nums, return the number of triplets chosen from the array that can make triangles if we take them as side lengths.
Java Solution:
public int triangleNumber(int[] nums) {
Arrays.sort(nums);
int count = 0;
for (int i = nums.length - 1; i >= 2; i--) {
int left = 0, right = i - 1;
while (left < right) {
if (nums[left] + nums[right] > nums[i]) {
count += right - left;
right--;
} else {
left++;
}
}
}
return count;
}
Explanation: Sort array. For each element as the largest side, use two pointers to find pairs where sum > largest side. If nums[left] + nums[right] > nums[i], all elements between left and right work with right.
- Time Complexity: O(n^2) - sorting + two pointer scan
- Space Complexity: O(1) - in-place sorting
612. Shortest Distance in a Plane
Description: SQL problem - Find the shortest distance between any two points in a 2D plane. Return the distance rounded to 2 decimal places.
Java Solution:
// This is a SQL problem, but here's a Java solution
public double shortestDistance(List<Point2D> points) {
if (points.size() < 2) return 0.0;
double minDist = Double.MAX_VALUE;
for (int i = 0; i < points.size(); i++) {
for (int j = i + 1; j < points.size(); j++) {
double dist = calculateDistance(points.get(i), points.get(j));
minDist = Math.min(minDist, dist);
}
}
return Math.round(minDist * 100.0) / 100.0;
}
private double calculateDistance(Point2D p1, Point2D p2) {
double dx = p1.x - p2.x;
double dy = p1.y - p2.y;
return Math.sqrt(dx * dx + dy * dy);
}
class Point2D {
double x;
double y;
}
Explanation: Calculate Euclidean distance between all pairs of points. Track minimum distance found. Round result to 2 decimal places.
- Time Complexity: O(n^2) - all pairs
- Space Complexity: O(1) - constant space
613. Shortest Distance in a Line
Description: SQL problem - Find the shortest distance between any two points on a number line.
Java Solution:
// This is a SQL problem, but here's a Java solution
public int shortestDistance(List<Point> points) {
if (points.size() < 2) return 0;
List<Integer> positions = new ArrayList<>();
for (Point p : points) {
positions.add(p.x);
}
Collections.sort(positions);
int minDist = Integer.MAX_VALUE;
for (int i = 1; i < positions.size(); i++) {
minDist = Math.min(minDist, positions.get(i) - positions.get(i - 1));
}
return minDist;
}
class Point {
int x;
}
Explanation: Sort points by position. Minimum distance is between adjacent points after sorting. Scan sorted list to find minimum difference.
- Time Complexity: O(n log n) - sorting
- Space Complexity: O(n) - sorted positions
614. Second Degree Follower
Description: SQL problem - Find followers who are also followed by others. A second degree follower is someone who follows someone and is also followed by others.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<FollowerCount> findSecondDegree(List<Follow> follows) {
Set<String> followers = new HashSet<>();
Map<String, Integer> followedCount = new HashMap<>();
for (Follow f : follows) {
followers.add(f.follower);
followedCount.put(f.followee,
followedCount.getOrDefault(f.followee, 0) + 1);
}
Map<String, Integer> result = new HashMap<>();
for (String follower : followers) {
if (followedCount.containsKey(follower)) {
result.put(follower, followedCount.get(follower));
}
}
List<FollowerCount> output = new ArrayList<>();
for (Map.Entry<String, Integer> entry : result.entrySet()) {
output.add(new FollowerCount(entry.getKey(), entry.getValue()));
}
return output;
}
class Follow {
String follower;
String followee;
}
class FollowerCount {
String follower;
int num;
FollowerCount(String follower, int num) {
this.follower = follower;
this.num = num;
}
}
Explanation: Track all followers and count how many followers each person has. Return people who are both followers (follow someone) and followees (followed by others).
- Time Complexity: O(n) - process all follow relationships
- Space Complexity: O(n) - sets and maps
615. Average Salary: Departments VS Company
Description: SQL problem - Compare average salary of each department with the company-wide average salary for each month. Return if department average is higher, lower, or same.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<Comparison> compareSalaries(List<Salary> salaries) {
// Group by month for company average
Map<String, List<Integer>> monthSalaries = new HashMap<>();
// Group by month and department
Map<String, Map<Integer, List<Integer>>> monthDeptSalaries = new HashMap<>();
for (Salary s : salaries) {
monthSalaries.computeIfAbsent(s.payMonth, k -> new ArrayList<>())
.add(s.amount);
monthDeptSalaries.computeIfAbsent(s.payMonth, k -> new HashMap<>())
.computeIfAbsent(s.departmentId, k -> new ArrayList<>())
.add(s.amount);
}
List<Comparison> result = new ArrayList<>();
for (String month : monthDeptSalaries.keySet()) {
double companyAvg = monthSalaries.get(month).stream()
.mapToInt(Integer::intValue).average().orElse(0);
for (Map.Entry<Integer, List<Integer>> deptEntry :
monthDeptSalaries.get(month).entrySet()) {
double deptAvg = deptEntry.getValue().stream()
.mapToInt(Integer::intValue).average().orElse(0);
String comparison;
if (deptAvg > companyAvg) comparison = "higher";
else if (deptAvg < companyAvg) comparison = "lower";
else comparison = "same";
result.add(new Comparison(month, deptEntry.getKey(), comparison));
}
}
return result;
}
class Salary {
int employeeId;
String payMonth;
int amount;
int departmentId;
}
class Comparison {
String payMonth;
int departmentId;
String comparison;
Comparison(String payMonth, int departmentId, String comparison) {
this.payMonth = payMonth;
this.departmentId = departmentId;
this.comparison = comparison;
}
}
Explanation: Group salaries by month and by month-department. Calculate company average per month and department average per month. Compare and return higher/lower/same for each department-month combination.
- Time Complexity: O(n) - process all salaries
- Space Complexity: O(n) - grouping maps
616. Add Bold Tag in String
Description:
Given a string s and an array of strings words, add bold tags <b> and </b> around all occurrences of any string in words. If two occurrences overlap, merge them.
Java Solution:
public String addBoldTag(String s, String[] words) {
boolean[] bold = new boolean[s.length()];
// Mark all positions that should be bold
for (String word : words) {
int start = 0;
while (start >= 0) {
start = s.indexOf(word, start);
if (start >= 0) {
for (int i = start; i < start + word.length(); i++) {
bold[i] = true;
}
start++;
}
}
}
// Build result with tags
StringBuilder result = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if (bold[i] && (i == 0 || !bold[i - 1])) {
result.append("<b>");
}
result.append(s.charAt(i));
if (bold[i] && (i == s.length() - 1 || !bold[i + 1])) {
result.append("</b>");
}
}
return result.toString();
}
Explanation: Mark all positions that should be bold using a boolean array. Find all occurrences of each word and mark those positions. Then build result string, adding opening tag at start of bold region and closing tag at end.
- Time Complexity: O(n * m * k) - n string length, m words, k average word length
- Space Complexity: O(n) - bold array
617. Merge Two Binary Trees
Description: Given two binary trees, merge them by overlapping nodes. If nodes overlap, sum their values. If one node is null, use the other.
Java Solution:
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if (root1 == null && root2 == null) return null;
if (root1 == null) return root2;
if (root2 == null) return root1;
TreeNode merged = new TreeNode(root1.val + root2.val);
merged.left = mergeTrees(root1.left, root2.left);
merged.right = mergeTrees(root1.right, root2.right);
return merged;
}
Explanation: Recursively merge trees. If both nodes exist, create new node with sum of values. If only one exists, use that node. Recursively process left and right subtrees.
- Time Complexity: O(min(m, n)) - visit overlapping nodes
- Space Complexity: O(min(m, n)) - recursion depth
618. Students Report By Geography
Description: SQL problem - Pivot table to display students from different continents (America, Asia, Europe) in separate columns.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<GeographyRow> pivotByGeography(List<Student> students) {
Map<String, List<String>> continentStudents = new HashMap<>();
for (Student s : students) {
continentStudents.computeIfAbsent(s.continent, k -> new ArrayList<>())
.add(s.name);
}
// Sort students in each continent
for (List<String> names : continentStudents.values()) {
Collections.sort(names);
}
List<String> america = continentStudents.getOrDefault("America", new ArrayList<>());
List<String> asia = continentStudents.getOrDefault("Asia", new ArrayList<>());
List<String> europe = continentStudents.getOrDefault("Europe", new ArrayList<>());
int maxRows = Math.max(Math.max(america.size(), asia.size()), europe.size());
List<GeographyRow> result = new ArrayList<>();
for (int i = 0; i < maxRows; i++) {
result.add(new GeographyRow(
i < america.size() ? america.get(i) : null,
i < asia.size() ? asia.get(i) : null,
i < europe.size() ? europe.get(i) : null
));
}
return result;
}
class Student {
String name;
String continent;
}
class GeographyRow {
String america;
String asia;
String europe;
GeographyRow(String america, String asia, String europe) {
this.america = america;
this.asia = asia;
this.europe = europe;
}
}
Explanation: Group students by continent and sort each group. Create rows where each row has one student from each continent (or null if continent has fewer students). Pivot the data into columnar format.
- Time Complexity: O(n log n) - sorting students
- Space Complexity: O(n) - grouped students
619. Biggest Single Number
Description: SQL problem - Find the largest number that appears only once. If no such number exists, return null.
Java Solution:
// This is a SQL problem, but here's a Java solution
public Integer findBiggestSingle(List<Integer> numbers) {
Map<Integer, Integer> count = new HashMap<>();
for (int num : numbers) {
count.put(num, count.getOrDefault(num, 0) + 1);
}
Integer maxSingle = null;
for (Map.Entry<Integer, Integer> entry : count.entrySet()) {
if (entry.getValue() == 1) {
if (maxSingle == null || entry.getKey() > maxSingle) {
maxSingle = entry.getKey();
}
}
}
return maxSingle;
}
Explanation: Count frequency of each number. Find numbers that appear exactly once. Return the maximum among those numbers, or null if none exist.
- Time Complexity: O(n) - count and find max
- Space Complexity: O(n) - frequency map
620. Not Boring Movies
Description: SQL problem - Find all movies with odd-numbered IDs and descriptions that are not “boring”. Return results ordered by rating in descending order.
Java Solution:
// This is a SQL problem, but here's a Java solution
public List<Movie> findInterestingMovies(List<Movie> movies) {
List<Movie> result = new ArrayList<>();
for (Movie movie : movies) {
if (movie.id % 2 == 1 && !"boring".equals(movie.description)) {
result.add(movie);
}
}
// Sort by rating descending
Collections.sort(result, (a, b) -> Double.compare(b.rating, a.rating));
return result;
}
class Movie {
int id;
String title;
String description;
double rating;
}
Explanation: Filter movies with odd IDs and non-boring descriptions. Sort filtered results by rating in descending order.
- Time Complexity: O(n log n) - filtering and sorting
- Space Complexity: O(k) - k matching movies
Comments