01 / 75·ArrayEasy

Two Sum

Given an array of integers nums and an integer target, return indices of the two numbers that add up to target. Each input has exactly one solution; you may not use the same element twice.

Input
nums = [2,7,11,15], target = 9
Output
[0,1]
Tap to reveal solutionLeetCode ↗
Solution · Java·ArrayEasy

Two Sum

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> seen = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int need = target - nums[i];
            if (seen.containsKey(need)) return new int[]{seen.get(need), i};
            seen.put(nums[i], i);
        }
        return new int[0];
    }
}
← Tap card to flip backLeetCode ↗
02 / 75·ArrayEasy

Best Time to Buy and Sell Stock

You are given an array prices where prices[i] is the price of a stock on day i. Choose one day to buy and a later day to sell to maximize profit. Return 0 if no profit is possible.

Input
prices = [7,1,5,3,6,4]
Output
5
Tap to reveal solutionLeetCode ↗
Solution · Java·ArrayEasy

Best Time to Buy and Sell Stock

class Solution {
    public int maxProfit(int[] prices) {
        int min = Integer.MAX_VALUE, profit = 0;
        for (int p : prices) {
            min = Math.min(min, p);
            profit = Math.max(profit, p - min);
        }
        return profit;
    }
}
← Tap card to flip backLeetCode ↗
03 / 75·ArrayEasy

Contains Duplicate

Given an integer array nums, return true if any value appears at least twice in the array, and false if every element is distinct.

Input
nums = [1,2,3,1]
Output
true
Tap to reveal solutionLeetCode ↗
Solution · Java·ArrayEasy

Contains Duplicate

class Solution {
    public boolean containsDuplicate(int[] nums) {
        Set<Integer> seen = new HashSet<>();
        for (int n : nums) if (!seen.add(n)) return true;
        return false;
    }
}
← Tap card to flip backLeetCode ↗
04 / 75·ArrayMedium

Product of Array Except Self

Given nums, return an array answer where answer[i] equals the product of all elements of nums except nums[i]. Solve in O(n) without using division.

Input
nums = [1,2,3,4]
Output
[24,12,8,6]
Tap to reveal solutionLeetCode ↗
Solution · Java·ArrayMedium

Product of Array Except Self

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int[] res = new int[n];
        int left = 1;
        for (int i = 0; i < n; i++) { res[i] = left; left *= nums[i]; }
        int right = 1;
        for (int i = n - 1; i >= 0; i--) { res[i] *= right; right *= nums[i]; }
        return res;
    }
}
← Tap card to flip backLeetCode ↗
05 / 75·ArrayMedium

Maximum Subarray

Given an integer array nums, find the contiguous subarray with the largest sum and return that sum. (Kadane's algorithm.)

Input
nums = [-2,1,-3,4,-1,2,1,-5,4]
Output
6
Note
Subarray [4,-1,2,1] has sum 6.
Tap to reveal solutionLeetCode ↗
Solution · Java·ArrayMedium

Maximum Subarray

class Solution {
    public int maxSubArray(int[] nums) {
        int cur = nums[0], best = nums[0];
        for (int i = 1; i < nums.length; i++) {
            cur = Math.max(nums[i], cur + nums[i]);
            best = Math.max(best, cur);
        }
        return best;
    }
}
← Tap card to flip backLeetCode ↗
06 / 75·ArrayMedium

Maximum Product Subarray

Given an integer array nums, find a contiguous subarray that has the largest product and return that product. Track both the running max and min because of negatives.

Input
nums = [2,3,-2,4]
Output
6
Tap to reveal solutionLeetCode ↗
Solution · Java·ArrayMedium

Maximum Product Subarray

class Solution {
    public int maxProduct(int[] nums) {
        int max = nums[0], min = nums[0], best = nums[0];
        for (int i = 1; i < nums.length; i++) {
            int n = nums[i];
            int a = n, b = n * max, c = n * min;
            int newMax = Math.max(a, Math.max(b, c));
            int newMin = Math.min(a, Math.min(b, c));
            max = newMax; min = newMin;
            best = Math.max(best, max);
        }
        return best;
    }
}
← Tap card to flip backLeetCode ↗
07 / 75·ArrayMedium

Find Minimum in Rotated Sorted Array

An ascending sorted array of unique elements has been rotated. Find the minimum element in O(log n).

Input
nums = [3,4,5,1,2]
Output
1
Tap to reveal solutionLeetCode ↗
Solution · Java·ArrayMedium

Find Minimum in Rotated Sorted Array

class Solution {
    public int findMin(int[] nums) {
        int l = 0, r = nums.length - 1;
        while (l < r) {
            int m = (l + r) >>> 1;
            if (nums[m] > nums[r]) l = m + 1;
            else r = m;
        }
        return nums[l];
    }
}
← Tap card to flip backLeetCode ↗
08 / 75·ArrayMedium

Search in Rotated Sorted Array

Given a rotated sorted array of distinct integers and a target, return its index, or -1 if not found. Must run in O(log n).

Input
nums = [4,5,6,7,0,1,2], target = 0
Output
4
Tap to reveal solutionLeetCode ↗
Solution · Java·ArrayMedium

Search in Rotated Sorted Array

class Solution {
    public int search(int[] nums, int target) {
        int l = 0, r = nums.length - 1;
        while (l <= r) {
            int m = (l + r) >>> 1;
            if (nums[m] == target) return m;
            if (nums[l] <= nums[m]) {
                if (nums[l] <= target && target < nums[m]) r = m - 1;
                else l = m + 1;
            } else {
                if (nums[m] < target && target <= nums[r]) l = m + 1;
                else r = m - 1;
            }
        }
        return -1;
    }
}
← Tap card to flip backLeetCode ↗
09 / 75·ArrayMedium

3Sum

Given nums, return all unique triplets [a,b,c] such that a+b+c == 0. The solution set must not contain duplicate triplets.

Input
nums = [-1,0,1,2,-1,-4]
Output
[[-1,-1,2],[-1,0,1]]
Tap to reveal solutionLeetCode ↗
Solution · Java·ArrayMedium

3Sum

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> res = new ArrayList<>();
        for (int i = 0; i < nums.length - 2; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            int l = i + 1, r = nums.length - 1;
            while (l < r) {
                int s = nums[i] + nums[l] + nums[r];
                if (s == 0) {
                    res.add(Arrays.asList(nums[i], nums[l], nums[r]));
                    while (l < r && nums[l] == nums[l + 1]) l++;
                    while (l < r && nums[r] == nums[r - 1]) r--;
                    l++; r--;
                } else if (s < 0) l++;
                else r--;
            }
        }
        return res;
    }
}
← Tap card to flip backLeetCode ↗
10 / 75·ArrayMedium

Container With Most Water

Given n non-negative integers representing wall heights, find two lines that with the x-axis form a container holding the most water.

Input
height = [1,8,6,2,5,4,8,3,7]
Output
49
Tap to reveal solutionLeetCode ↗
Solution · Java·ArrayMedium

Container With Most Water

class Solution {
    public int maxArea(int[] height) {
        int l = 0, r = height.length - 1, best = 0;
        while (l < r) {
            int h = Math.min(height[l], height[r]);
            best = Math.max(best, h * (r - l));
            if (height[l] < height[r]) l++; else r--;
        }
        return best;
    }
}
← Tap card to flip backLeetCode ↗
11 / 75·BinaryMedium

Sum of Two Integers

Given two integers a and b, return their sum without using the operators + or -. Use bit manipulation: XOR for sum-without-carry, AND+shift for carry.

Input
a = 1, b = 2
Output
3
Tap to reveal solutionLeetCode ↗
Solution · Java·BinaryMedium

Sum of Two Integers

class Solution {
    public int getSum(int a, int b) {
        while (b != 0) {
            int carry = (a & b) << 1;
            a = a ^ b;
            b = carry;
        }
        return a;
    }
}
← Tap card to flip backLeetCode ↗
12 / 75·BinaryEasy

Number of 1 Bits

Write a function that takes an unsigned integer and returns the number of 1 bits (Hamming weight). Trick: n & (n-1) clears the lowest set bit.

Input
n = 11 (0b1011)
Output
3
Tap to reveal solutionLeetCode ↗
Solution · Java·BinaryEasy

Number of 1 Bits

public class Solution {
    public int hammingWeight(int n) {
        int count = 0;
        while (n != 0) { n &= n - 1; count++; }
        return count;
    }
}
← Tap card to flip backLeetCode ↗
13 / 75·BinaryEasy

Counting Bits

Given n, return an array of length n+1 where ans[i] is the number of 1's in the binary representation of i. Solve in O(n).

Input
n = 5
Output
[0,1,1,2,1,2]
Tap to reveal solutionLeetCode ↗
Solution · Java·BinaryEasy

Counting Bits

class Solution {
    public int[] countBits(int n) {
        int[] dp = new int[n + 1];
        for (int i = 1; i <= n; i++) dp[i] = dp[i >> 1] + (i & 1);
        return dp;
    }
}
← Tap card to flip backLeetCode ↗
14 / 75·BinaryEasy

Missing Number

Given an array nums containing n distinct numbers in [0, n], return the only number in the range that is missing.

Input
nums = [3,0,1]
Output
2
Tap to reveal solutionLeetCode ↗
Solution · Java·BinaryEasy

Missing Number

class Solution {
    public int missingNumber(int[] nums) {
        int n = nums.length;
        int sum = n * (n + 1) / 2;
        for (int x : nums) sum -= x;
        return sum;
    }
}
← Tap card to flip backLeetCode ↗
15 / 75·BinaryEasy

Reverse Bits

Reverse the bits of a 32-bit unsigned integer. Shift the answer left and OR in the lowest bit of n; then shift n right.

Input
n = 0b00000010100101000001111010011100
Output
0b00111001011110000010100101000000
Tap to reveal solutionLeetCode ↗
Solution · Java·BinaryEasy

Reverse Bits

public class Solution {
    public int reverseBits(int n) {
        int res = 0;
        for (int i = 0; i < 32; i++) {
            res = (res << 1) | (n & 1);
            n >>>= 1;
        }
        return res;
    }
}
← Tap card to flip backLeetCode ↗
16 / 75·DPEasy

Climbing Stairs

You can climb 1 or 2 steps at a time. How many distinct ways can you reach step n? (Fibonacci.)

Input
n = 3
Output
3
Tap to reveal solutionLeetCode ↗
Solution · Java·DPEasy

Climbing Stairs

class Solution {
    public int climbStairs(int n) {
        int a = 1, b = 1;
        for (int i = 2; i <= n; i++) {
            int t = a + b; a = b; b = t;
        }
        return b;
    }
}
← Tap card to flip backLeetCode ↗
17 / 75·DPMedium

Coin Change

Given coin denominations and an amount, return the fewest number of coins needed to make up that amount. Return -1 if impossible.

Input
coins = [1,2,5], amount = 11
Output
3
Tap to reveal solutionLeetCode ↗
Solution · Java·DPMedium

Coin Change

class 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 c : coins)
                if (i - c >= 0) dp[i] = Math.min(dp[i], dp[i - c] + 1);
        return dp[amount] > amount ? -1 : dp[amount];
    }
}
← Tap card to flip backLeetCode ↗
18 / 75·DPMedium

Longest Increasing Subsequence

Given an integer array nums, return the length of the longest strictly increasing subsequence. Patience sort gives O(n log n).

Input
nums = [10,9,2,5,3,7,101,18]
Output
4
Tap to reveal solutionLeetCode ↗
Solution · Java·DPMedium

Longest Increasing Subsequence

class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] tails = new int[nums.length];
        int size = 0;
        for (int x : nums) {
            int l = 0, r = size;
            while (l < r) {
                int m = (l + r) >>> 1;
                if (tails[m] < x) l = m + 1;
                else r = m;
            }
            tails[l] = x;
            if (l == size) size++;
        }
        return size;
    }
}
← Tap card to flip backLeetCode ↗
19 / 75·DPMedium

Longest Common Subsequence

Given two strings text1 and text2, return the length of their longest common subsequence (not necessarily contiguous).

Input
text1 = "abcde", text2 = "ace"
Output
3
Tap to reveal solutionLeetCode ↗
Solution · Java·DPMedium

Longest Common Subsequence

class Solution {
    public int longestCommonSubsequence(String a, String b) {
        int m = a.length(), n = b.length();
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++)
                dp[i][j] = a.charAt(i - 1) == b.charAt(j - 1)
                    ? dp[i - 1][j - 1] + 1
                    : Math.max(dp[i - 1][j], dp[i][j - 1]);
        return dp[m][n];
    }
}
← Tap card to flip backLeetCode ↗
20 / 75·DPMedium

Word Break

Given string s and a dictionary of words, return true if s can be segmented into a space-separated sequence of dictionary words.

Input
s = "leetcode", wordDict = ["leet","code"]
Output
true
Tap to reveal solutionLeetCode ↗
Solution · Java·DPMedium

Word Break

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        Set<String> set = 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] && set.contains(s.substring(j, i))) {
                    dp[i] = true; break;
                }
        return dp[s.length()];
    }
}
← Tap card to flip backLeetCode ↗
21 / 75·DPMedium

Combination Sum IV

Given an array of distinct positive integers nums and a target, return the number of possible orderings (sequences) that sum to target.

Input
nums = [1,2,3], target = 4
Output
7
Tap to reveal solutionLeetCode ↗
Solution · Java·DPMedium

Combination Sum IV

class 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 n : nums)
                if (i - n >= 0) dp[i] += dp[i - n];
        return dp[target];
    }
}
← Tap card to flip backLeetCode ↗
22 / 75·DPMedium

House Robber

Given non-negative integers representing money in each house, return the max you can rob without robbing two adjacent houses.

Input
nums = [2,7,9,3,1]
Output
12
Tap to reveal solutionLeetCode ↗
Solution · Java·DPMedium

House Robber

class Solution {
    public int rob(int[] nums) {
        int prev = 0, curr = 0;
        for (int n : nums) {
            int next = Math.max(curr, prev + n);
            prev = curr; curr = next;
        }
        return curr;
    }
}
← Tap card to flip backLeetCode ↗
23 / 75·DPMedium

House Robber II

Same as House Robber, but the houses are arranged in a circle (first and last are adjacent). Run House Robber on nums[1:] and nums[:-1].

Input
nums = [2,3,2]
Output
3
Tap to reveal solutionLeetCode ↗
Solution · Java·DPMedium

House Robber II

class Solution {
    public int rob(int[] nums) {
        if (nums.length == 1) return nums[0];
        return Math.max(
            linear(nums, 0, nums.length - 2),
            linear(nums, 1, nums.length - 1));
    }
    private int linear(int[] nums, int lo, int hi) {
        int prev = 0, curr = 0;
        for (int i = lo; i <= hi; i++) {
            int next = Math.max(curr, prev + nums[i]);
            prev = curr; curr = next;
        }
        return curr;
    }
}
← Tap card to flip backLeetCode ↗
24 / 75·DPMedium

Decode Ways

A message of digits encodes letters: 'A'=1 ... 'Z'=26. Return the number of ways to decode the string.

Input
s = "12"
Output
2
Note
'AB' or 'L'
Tap to reveal solutionLeetCode ↗
Solution · Java·DPMedium

Decode Ways

class Solution {
    public int numDecodings(String s) {
        if (s.charAt(0) == '0') return 0;
        int n = s.length();
        int[] dp = new int[n + 1];
        dp[0] = 1; dp[1] = 1;
        for (int i = 2; i <= n; i++) {
            if (s.charAt(i - 1) != '0') dp[i] += dp[i - 1];
            int two = Integer.parseInt(s.substring(i - 2, i));
            if (two >= 10 && two <= 26) dp[i] += dp[i - 2];
        }
        return dp[n];
    }
}
← Tap card to flip backLeetCode ↗
25 / 75·DPMedium

Unique Paths

On an m x n grid, a robot at top-left moves only right or down. How many distinct paths reach the bottom-right?

Input
m = 3, n = 7
Output
28
Tap to reveal solutionLeetCode ↗
Solution · Java·DPMedium

Unique Paths

class 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];
    }
}
← Tap card to flip backLeetCode ↗
26 / 75·DPMedium

Jump Game

Given nums where nums[i] is the max jump length from index i, can you reach the last index? Greedy: track furthest reach.

Input
nums = [2,3,1,1,4]
Output
true
Tap to reveal solutionLeetCode ↗
Solution · Java·DPMedium

Jump Game

class Solution {
    public boolean canJump(int[] nums) {
        int reach = 0;
        for (int i = 0; i < nums.length; i++) {
            if (i > reach) return false;
            reach = Math.max(reach, i + nums[i]);
        }
        return true;
    }
}
← Tap card to flip backLeetCode ↗
27 / 75·GraphMedium

Clone Graph

Given a reference to a node in a connected undirected graph, return a deep copy of the graph. Use DFS + a Map from original to clone.

Input
adjList = [[2,4],[1,3],[2,4],[1,3]]
Output
deep copy
Tap to reveal solutionLeetCode ↗
Solution · Java·GraphMedium

Clone Graph

class Solution {
    public Node cloneGraph(Node node) {
        if (node == null) return null;
        return dfs(node, new HashMap<>());
    }
    private Node dfs(Node n, Map<Node, Node> map) {
        if (map.containsKey(n)) return map.get(n);
        Node copy = new Node(n.val);
        map.put(n, copy);
        for (Node nb : n.neighbors) copy.neighbors.add(dfs(nb, map));
        return copy;
    }
}
← Tap card to flip backLeetCode ↗
28 / 75·GraphMedium

Course Schedule

n courses labeled 0..n-1 with prerequisite pairs [a,b] meaning b must precede a. Return true if all courses can be finished (no cycles). Use Kahn's topological sort.

Input
n = 2, prerequisites = [[1,0]]
Output
true
Tap to reveal solutionLeetCode ↗
Solution · Java·GraphMedium

Course Schedule

class Solution {
    public boolean canFinish(int n, int[][] prereq) {
        List<List<Integer>> graph = new ArrayList<>();
        for (int i = 0; i < n; i++) graph.add(new ArrayList<>());
        int[] indeg = new int[n];
        for (int[] p : prereq) { graph.get(p[1]).add(p[0]); indeg[p[0]]++; }
        Queue<Integer> q = new ArrayDeque<>();
        for (int i = 0; i < n; i++) if (indeg[i] == 0) q.offer(i);
        int done = 0;
        while (!q.isEmpty()) {
            int c = q.poll(); done++;
            for (int nx : graph.get(c)) if (--indeg[nx] == 0) q.offer(nx);
        }
        return done == n;
    }
}
← Tap card to flip backLeetCode ↗
29 / 75·GraphMedium

Pacific Atlantic Water Flow

Given an m x n matrix of heights, water flows to a neighbor if its height is <=. Return cells from which water can flow to BOTH the Pacific (top/left) and Atlantic (bottom/right).

Input
heights = [[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]]
Output
[[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]]
Tap to reveal solutionLeetCode ↗
Solution · Java·GraphMedium

Pacific Atlantic Water Flow

class Solution {
    int m, n;
    int[][] heights;
    public List<List<Integer>> pacificAtlantic(int[][] heights) {
        this.heights = heights;
        m = heights.length; n = heights[0].length;
        boolean[][] pac = new boolean[m][n], atl = new boolean[m][n];
        for (int i = 0; i < m; i++) {
            dfs(i, 0, pac, Integer.MIN_VALUE);
            dfs(i, n - 1, atl, Integer.MIN_VALUE);
        }
        for (int j = 0; j < n; j++) {
            dfs(0, j, pac, Integer.MIN_VALUE);
            dfs(m - 1, j, atl, Integer.MIN_VALUE);
        }
        List<List<Integer>> res = new ArrayList<>();
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                if (pac[i][j] && atl[i][j]) res.add(Arrays.asList(i, j));
        return res;
    }
    private void dfs(int r, int c, boolean[][] seen, int prev) {
        if (r < 0 || c < 0 || r >= m || c >= n) return;
        if (seen[r][c] || heights[r][c] < prev) return;
        seen[r][c] = true;
        dfs(r+1,c,seen,heights[r][c]);
        dfs(r-1,c,seen,heights[r][c]);
        dfs(r,c+1,seen,heights[r][c]);
        dfs(r,c-1,seen,heights[r][c]);
    }
}
← Tap card to flip backLeetCode ↗
30 / 75·GraphMedium

Number of Islands

Given an m x n grid of '1' (land) and '0' (water), return the number of islands. An island is a group of '1's connected 4-directionally.

Input
grid = [["1","1","0"],["1","0","0"],["0","0","1"]]
Output
2
Tap to reveal solutionLeetCode ↗
Solution · Java·GraphMedium

Number of Islands

class Solution {
    public int numIslands(char[][] grid) {
        int m = grid.length, n = grid[0].length, count = 0;
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                if (grid[i][j] == '1') { count++; dfs(grid, i, j, m, n); }
        return count;
    }
    private void dfs(char[][] g, int r, int c, int m, int n) {
        if (r < 0 || c < 0 || r >= m || c >= n || g[r][c] != '1') return;
        g[r][c] = '0';
        dfs(g, r+1, c, m, n); dfs(g, r-1, c, m, n);
        dfs(g, r, c+1, m, n); dfs(g, r, c-1, m, n);
    }
}
← Tap card to flip backLeetCode ↗
31 / 75·GraphMedium

Longest Consecutive Sequence

Given an unsorted array, return the length of the longest consecutive elements sequence. Solve in O(n). Only start counting from sequence starts.

Input
nums = [100,4,200,1,3,2]
Output
4
Tap to reveal solutionLeetCode ↗
Solution · Java·GraphMedium

Longest Consecutive Sequence

class Solution {
    public int longestConsecutive(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for (int n : nums) set.add(n);
        int best = 0;
        for (int n : set) {
            if (!set.contains(n - 1)) {
                int cur = n, len = 1;
                while (set.contains(cur + 1)) { cur++; len++; }
                best = Math.max(best, len);
            }
        }
        return best;
    }
}
← Tap card to flip backLeetCode ↗
32 / 75·GraphHard

Alien Dictionary

Given a sorted list of words from an alien language, derive the order of letters. Build a graph from each adjacent word pair and topo-sort.

Input
words = ["wrt","wrf","er","ett","rftt"]
Output
"wertf"
Tap to reveal solutionLeetCode ↗
Solution · Java·GraphHard

Alien Dictionary

class Solution {
    public String alienOrder(String[] words) {
        Map<Character, Set<Character>> graph = new HashMap<>();
        Map<Character, Integer> indeg = new HashMap<>();
        for (String w : words)
            for (char c : w.toCharArray()) {
                graph.putIfAbsent(c, new HashSet<>());
                indeg.putIfAbsent(c, 0);
            }
        for (int i = 0; i < words.length - 1; i++) {
            String a = words[i], b = words[i + 1];
            if (a.length() > b.length() && a.startsWith(b)) return "";
            for (int j = 0; j < Math.min(a.length(), b.length()); j++) {
                char x = a.charAt(j), y = b.charAt(j);
                if (x != y) {
                    if (graph.get(x).add(y)) indeg.merge(y, 1, Integer::sum);
                    break;
                }
            }
        }
        Queue<Character> q = new ArrayDeque<>();
        for (Map.Entry<Character, Integer> e : indeg.entrySet())
            if (e.getValue() == 0) q.offer(e.getKey());
        StringBuilder sb = new StringBuilder();
        while (!q.isEmpty()) {
            char c = q.poll();
            sb.append(c);
            for (char nx : graph.get(c))
                if (indeg.merge(nx, -1, Integer::sum) == 0) q.offer(nx);
        }
        return sb.length() == indeg.size() ? sb.toString() : "";
    }
}
← Tap card to flip backLeetCode ↗
33 / 75·GraphMedium

Graph Valid Tree

Given n nodes (0..n-1) and a list of edges, decide if these edges form a valid tree. A valid tree has exactly n-1 edges, is connected, and has no cycles.

Input
n = 5, edges = [[0,1],[0,2],[0,3],[1,4]]
Output
true
Tap to reveal solutionLeetCode ↗
Solution · Java·GraphMedium

Graph Valid Tree

class Solution {
    int[] parent;
    public boolean validTree(int n, int[][] edges) {
        if (edges.length != n - 1) return false;
        parent = new int[n];
        for (int i = 0; i < n; i++) parent[i] = i;
        for (int[] e : edges) {
            int ra = find(e[0]), rb = find(e[1]);
            if (ra == rb) return false;
            parent[ra] = rb;
        }
        return true;
    }
    private int find(int x) {
        while (parent[x] != x) { parent[x] = parent[parent[x]]; x = parent[x]; }
        return x;
    }
}
← Tap card to flip backLeetCode ↗
34 / 75·GraphMedium

Number of Connected Components

Given n nodes and an array of edges in an undirected graph, return the number of connected components. Union-Find: start with n components and decrement on each successful union.

Input
n = 5, edges = [[0,1],[1,2],[3,4]]
Output
2
Tap to reveal solutionLeetCode ↗
Solution · Java·GraphMedium

Number of Connected Components

class Solution {
    int[] parent;
    public int countComponents(int n, int[][] edges) {
        parent = new int[n];
        for (int i = 0; i < n; i++) parent[i] = i;
        int count = n;
        for (int[] e : edges) {
            int ra = find(e[0]), rb = find(e[1]);
            if (ra != rb) { parent[ra] = rb; count--; }
        }
        return count;
    }
    private int find(int x) {
        while (parent[x] != x) { parent[x] = parent[parent[x]]; x = parent[x]; }
        return x;
    }
}
← Tap card to flip backLeetCode ↗
35 / 75·IntervalMedium

Insert Interval

Given non-overlapping intervals sorted by start, insert a new interval (merging if necessary) and return the result.

Input
intervals = [[1,3],[6,9]], newInterval = [2,5]
Output
[[1,5],[6,9]]
Tap to reveal solutionLeetCode ↗
Solution · Java·IntervalMedium

Insert Interval

class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
        List<int[]> res = new ArrayList<>();
        int i = 0, n = intervals.length;
        while (i < n && intervals[i][1] < newInterval[0]) res.add(intervals[i++]);
        while (i < n && intervals[i][0] <= newInterval[1]) {
            newInterval[0] = Math.min(newInterval[0], intervals[i][0]);
            newInterval[1] = Math.max(newInterval[1], intervals[i][1]);
            i++;
        }
        res.add(newInterval);
        while (i < n) res.add(intervals[i++]);
        return res.toArray(new int[0][]);
    }
}
← Tap card to flip backLeetCode ↗
36 / 75·IntervalMedium

Merge Intervals

Given an array of intervals, merge all overlapping intervals and return the merged list. Sort by start; merge by extending the last interval's end.

Input
intervals = [[1,3],[2,6],[8,10],[15,18]]
Output
[[1,6],[8,10],[15,18]]
Tap to reveal solutionLeetCode ↗
Solution · Java·IntervalMedium

Merge Intervals

class Solution {
    public int[][] merge(int[][] intervals) {
        Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
        List<int[]> res = new ArrayList<>();
        res.add(intervals[0]);
        for (int i = 1; i < intervals.length; i++) {
            int[] last = res.get(res.size() - 1);
            if (intervals[i][0] <= last[1]) last[1] = Math.max(last[1], intervals[i][1]);
            else res.add(intervals[i]);
        }
        return res.toArray(new int[0][]);
    }
}
← Tap card to flip backLeetCode ↗
37 / 75·IntervalMedium

Non-overlapping Intervals

Given intervals, return the minimum number you must remove so that the rest are non-overlapping. Greedy by earliest end time.

Input
intervals = [[1,2],[2,3],[3,4],[1,3]]
Output
1
Tap to reveal solutionLeetCode ↗
Solution · Java·IntervalMedium

Non-overlapping Intervals

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        Arrays.sort(intervals, (a, b) -> a[1] - b[1]);
        int end = Integer.MIN_VALUE, removed = 0;
        for (int[] iv : intervals) {
            if (iv[0] >= end) end = iv[1];
            else removed++;
        }
        return removed;
    }
}
← Tap card to flip backLeetCode ↗
38 / 75·IntervalEasy

Meeting Rooms

Given an array of meeting time intervals, determine if a person could attend all meetings (no overlaps).

Input
intervals = [[0,30],[5,10],[15,20]]
Output
false
Tap to reveal solutionLeetCode ↗
Solution · Java·IntervalEasy

Meeting Rooms

class 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;
    }
}
← Tap card to flip backLeetCode ↗
39 / 75·IntervalMedium

Meeting Rooms II

Given meeting intervals, return the minimum number of conference rooms needed. Use sorted starts/ends two-pointer or a min-heap of end times.

Input
intervals = [[0,30],[5,10],[15,20]]
Output
2
Tap to reveal solutionLeetCode ↗
Solution · Java·IntervalMedium

Meeting Rooms II

class Solution {
    public int minMeetingRooms(int[][] intervals) {
        int n = intervals.length;
        int[] starts = new int[n], ends = new int[n];
        for (int i = 0; i < n; i++) {
            starts[i] = intervals[i][0];
            ends[i] = intervals[i][1];
        }
        Arrays.sort(starts);
        Arrays.sort(ends);
        int rooms = 0, e = 0;
        for (int s = 0; s < n; s++) {
            if (starts[s] < ends[e]) rooms++;
            else e++;
        }
        return rooms;
    }
}
← Tap card to flip backLeetCode ↗
40 / 75·Linked ListEasy

Reverse Linked List

Given the head of a singly linked list, reverse the list and return the new head.

Input
1->2->3->4->5
Output
5->4->3->2->1
Tap to reveal solutionLeetCode ↗
Solution · Java·Linked ListEasy

Reverse Linked List

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null, curr = head;
        while (curr != null) {
            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }
}
← Tap card to flip backLeetCode ↗
41 / 75·Linked ListEasy

Linked List Cycle

Given head of a linked list, determine if it contains a cycle. Floyd's tortoise & hare: slow moves 1, fast moves 2; they meet inside any cycle.

Input
head = [3,2,0,-4], pos = 1
Output
true
Tap to reveal solutionLeetCode ↗
Solution · Java·Linked ListEasy

Linked List Cycle

public class 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;
    }
}
← Tap card to flip backLeetCode ↗
42 / 75·Linked ListEasy

Merge Two Sorted Lists

Merge two sorted linked lists and return as a single sorted list, splicing nodes (no new node creation needed).

Input
l1 = [1,2,4], l2 = [1,3,4]
Output
[1,1,2,3,4,4]
Tap to reveal solutionLeetCode ↗
Solution · Java·Linked ListEasy

Merge Two Sorted Lists

class Solution {
    public ListNode mergeTwoLists(ListNode a, ListNode b) {
        ListNode dummy = new ListNode(0), tail = dummy;
        while (a != null && b != null) {
            if (a.val <= b.val) { tail.next = a; a = a.next; }
            else { tail.next = b; b = b.next; }
            tail = tail.next;
        }
        tail.next = a != null ? a : b;
        return dummy.next;
    }
}
← Tap card to flip backLeetCode ↗
43 / 75·Linked ListHard

Merge K Sorted Lists

Given an array of k sorted linked lists, merge them into one sorted list. Pairwise merge (divide & conquer) is O(N log k).

Input
lists = [[1,4,5],[1,3,4],[2,6]]
Output
[1,1,2,3,4,4,5,6]
Tap to reveal solutionLeetCode ↗
Solution · Java·Linked ListHard

Merge K Sorted Lists

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists.length == 0) return null;
        int interval = 1;
        while (interval < lists.length) {
            for (int i = 0; i + interval < lists.length; i += interval * 2)
                lists[i] = merge(lists[i], lists[i + interval]);
            interval *= 2;
        }
        return lists[0];
    }
    private ListNode merge(ListNode a, ListNode b) {
        ListNode dummy = new ListNode(0), t = dummy;
        while (a != null && b != null) {
            if (a.val <= b.val) { t.next = a; a = a.next; }
            else { t.next = b; b = b.next; }
            t = t.next;
        }
        t.next = a != null ? a : b;
        return dummy.next;
    }
}
← Tap card to flip backLeetCode ↗
44 / 75·Linked ListMedium

Remove Nth Node From End

Given the head of a linked list, remove the nth node from the end and return the head. Use two pointers: advance fast n+1 steps first.

Input
head = [1,2,3,4,5], n = 2
Output
[1,2,3,5]
Tap to reveal solutionLeetCode ↗
Solution · Java·Linked ListMedium

Remove Nth Node From End

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode fast = dummy, slow = dummy;
        for (int i = 0; i <= n; i++) fast = fast.next;
        while (fast != null) { fast = fast.next; slow = slow.next; }
        slow.next = slow.next.next;
        return dummy.next;
    }
}
← Tap card to flip backLeetCode ↗
45 / 75·Linked ListMedium

Reorder List

Given L0->L1->...->Ln-1, reorder it to L0->Ln-1->L1->Ln-2->L2->Ln-3->... in place. Steps: find middle, reverse second half, weave the two halves.

Input
[1,2,3,4]
Output
[1,4,2,3]
Tap to reveal solutionLeetCode ↗
Solution · Java·Linked ListMedium

Reorder List

class Solution {
    public void reorderList(ListNode head) {
        if (head == null) return;
        ListNode slow = head, fast = head;
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode prev = null, curr = slow.next;
        slow.next = null;
        while (curr != null) {
            ListNode n = curr.next;
            curr.next = prev;
            prev = curr;
            curr = n;
        }
        ListNode a = head, b = prev;
        while (b != null) {
            ListNode an = a.next, bn = b.next;
            a.next = b;
            b.next = an;
            a = an;
            b = bn;
        }
    }
}
← Tap card to flip backLeetCode ↗
46 / 75·MatrixMedium

Set Matrix Zeroes

Given an m x n matrix, if a cell is 0, set its entire row and column to 0 — in place. Use the first row/col as markers; track them separately.

Input
matrix = [[1,1,1],[1,0,1],[1,1,1]]
Output
[[1,0,1],[0,0,0],[1,0,1]]
Tap to reveal solutionLeetCode ↗
Solution · Java·MatrixMedium

Set Matrix Zeroes

class Solution {
    public void setZeroes(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        boolean firstRow = false, firstCol = false;
        for (int j = 0; j < n; j++) if (matrix[0][j] == 0) firstRow = true;
        for (int i = 0; i < m; i++) if (matrix[i][0] == 0) firstCol = 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 (firstRow) for (int j = 0; j < n; j++) matrix[0][j] = 0;
        if (firstCol) for (int i = 0; i < m; i++) matrix[i][0] = 0;
    }
}
← Tap card to flip backLeetCode ↗
47 / 75·MatrixMedium

Spiral Matrix

Given an m x n matrix, return all elements in spiral order (right, down, left, up — repeat). Track top/bottom/left/right boundaries.

Input
matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output
[1,2,3,6,9,8,7,4,5]
Tap to reveal solutionLeetCode ↗
Solution · Java·MatrixMedium

Spiral Matrix

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> res = new ArrayList<>();
        int top = 0, bot = matrix.length - 1;
        int left = 0, right = matrix[0].length - 1;
        while (top <= bot && left <= right) {
            for (int j = left; j <= right; j++) res.add(matrix[top][j]);
            top++;
            for (int i = top; i <= bot; i++) res.add(matrix[i][right]);
            right--;
            if (top <= bot)
                for (int j = right; j >= left; j--) res.add(matrix[bot][j]);
            bot--;
            if (left <= right)
                for (int i = bot; i >= top; i--) res.add(matrix[i][left]);
            left++;
        }
        return res;
    }
}
← Tap card to flip backLeetCode ↗
48 / 75·MatrixMedium

Rotate Image

Rotate an n x n matrix 90 degrees clockwise in place. Trick: transpose, then reverse each row.

Input
matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output
[[7,4,1],[8,5,2],[9,6,3]]
Tap to reveal solutionLeetCode ↗
Solution · Java·MatrixMedium

Rotate Image

class Solution {
    public void rotate(int[][] matrix) {
        int n = matrix.length;
        for (int i = 0; i < n; i++)
            for (int j = i + 1; j < n; j++) {
                int t = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = t;
            }
        for (int[] row : matrix) {
            int l = 0, r = row.length - 1;
            while (l < r) { int t = row[l]; row[l] = row[r]; row[r] = t; l++; r--; }
        }
    }
}
← Tap card to flip backLeetCode ↗
49 / 75·MatrixMedium

Word Search

Given an m x n grid of letters and a word, return true if the word can be constructed from sequentially adjacent cells. The same cell may not be used twice.

Input
board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
Output
true
Tap to reveal solutionLeetCode ↗
Solution · Java·MatrixMedium

Word Search

class Solution {
    public boolean exist(char[][] board, String word) {
        int m = board.length, n = board[0].length;
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                if (dfs(board, i, j, 0, word, m, n)) return true;
        return false;
    }
    private boolean dfs(char[][] b, int r, int c, int k, String w, int m, int n) {
        if (k == w.length()) return true;
        if (r < 0 || c < 0 || r >= m || c >= n || b[r][c] != w.charAt(k)) return false;
        char tmp = b[r][c];
        b[r][c] = '#';
        boolean found = dfs(b, r+1, c, k+1, w, m, n)
                     || dfs(b, r-1, c, k+1, w, m, n)
                     || dfs(b, r, c+1, k+1, w, m, n)
                     || dfs(b, r, c-1, k+1, w, m, n);
        b[r][c] = tmp;
        return found;
    }
}
← Tap card to flip backLeetCode ↗
50 / 75·StringMedium

Longest Substring Without Repeating Characters

Given a string s, find the length of the longest substring without repeating characters. Sliding window with a Map of last-seen indices.

Input
s = "abcabcbb"
Output
3
Tap to reveal solutionLeetCode ↗
Solution · Java·StringMedium

Longest Substring Without Repeating Characters

class Solution {
    public int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> map = new HashMap<>();
        int l = 0, best = 0;
        for (int r = 0; r < s.length(); r++) {
            char c = s.charAt(r);
            if (map.containsKey(c) && map.get(c) >= l) l = map.get(c) + 1;
            map.put(c, r);
            best = Math.max(best, r - l + 1);
        }
        return best;
    }
}
← Tap card to flip backLeetCode ↗
51 / 75·StringMedium

Longest Repeating Character Replacement

Given string s and integer k, you may replace at most k characters with any letter. Return the length of the longest substring containing the same letter.

Input
s = "AABABBA", k = 1
Output
4
Tap to reveal solutionLeetCode ↗
Solution · Java·StringMedium

Longest Repeating Character Replacement

class Solution {
    public int characterReplacement(String s, int k) {
        int[] count = new int[26];
        int l = 0, maxCount = 0, best = 0;
        for (int r = 0; r < s.length(); r++) {
            int idx = s.charAt(r) - 'A';
            count[idx]++;
            maxCount = Math.max(maxCount, count[idx]);
            if (r - l + 1 - maxCount > k) {
                count[s.charAt(l) - 'A']--;
                l++;
            }
            best = Math.max(best, r - l + 1);
        }
        return best;
    }
}
← Tap card to flip backLeetCode ↗
52 / 75·StringHard

Minimum Window Substring

Given strings s and t, return the minimum window substring of s such that every character in t (including counts) is included in the window. Sliding window + counts.

Input
s = "ADOBECODEBANC", t = "ABC"
Output
"BANC"
Tap to reveal solutionLeetCode ↗
Solution · Java·StringHard

Minimum Window Substring

class Solution {
    public String minWindow(String s, String t) {
        Map<Character, Integer> need = new HashMap<>();
        for (char c : t.toCharArray()) need.merge(c, 1, Integer::sum);
        int have = 0, required = need.size();
        int l = 0, bestLen = Integer.MAX_VALUE, bestL = 0;
        Map<Character, Integer> window = new HashMap<>();
        for (int r = 0; r < s.length(); r++) {
            char c = s.charAt(r);
            window.merge(c, 1, Integer::sum);
            if (need.containsKey(c) && window.get(c).intValue() == need.get(c).intValue()) have++;
            while (have == required) {
                if (r - l + 1 < bestLen) { bestLen = r - l + 1; bestL = l; }
                char lc = s.charAt(l);
                window.merge(lc, -1, Integer::sum);
                if (need.containsKey(lc) && window.get(lc) < need.get(lc)) have--;
                l++;
            }
        }
        return bestLen == Integer.MAX_VALUE ? "" : s.substring(bestL, bestL + bestLen);
    }
}
← Tap card to flip backLeetCode ↗
53 / 75·StringEasy

Valid Anagram

Given two strings s and t, return true if t is an anagram of s. Compare character counts.

Input
s = "anagram", t = "nagaram"
Output
true
Tap to reveal solutionLeetCode ↗
Solution · Java·StringEasy

Valid Anagram

class 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 x : count) if (x != 0) return false;
        return true;
    }
}
← Tap card to flip backLeetCode ↗
54 / 75·StringMedium

Group Anagrams

Given an array of strings, group the anagrams together. Use a sorted version of each string as the bucket key.

Input
strs = ["eat","tea","tan","ate","nat","bat"]
Output
[["eat","tea","ate"],["tan","nat"],["bat"]]
Tap to reveal solutionLeetCode ↗
Solution · Java·StringMedium

Group Anagrams

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<>();
        for (String s : strs) {
            char[] arr = s.toCharArray();
            Arrays.sort(arr);
            String key = new String(arr);
            map.computeIfAbsent(key, k -> new ArrayList<>()).add(s);
        }
        return new ArrayList<>(map.values());
    }
}
← Tap card to flip backLeetCode ↗
55 / 75·StringEasy

Valid Parentheses

Given a string of '()[]{}', determine if the input has properly matched and nested brackets.

Input
s = "()[]{}"
Output
true
Tap to reveal solutionLeetCode ↗
Solution · Java·StringEasy

Valid Parentheses

class Solution {
    public boolean isValid(String s) {
        Deque<Character> stack = new ArrayDeque<>();
        for (char c : s.toCharArray()) {
            if (c == '(' || c == '[' || c == '{') stack.push(c);
            else {
                if (stack.isEmpty()) return false;
                char top = stack.pop();
                if (c == ')' && top != '(') return false;
                if (c == ']' && top != '[') return false;
                if (c == '}' && top != '{') return false;
            }
        }
        return stack.isEmpty();
    }
}
← Tap card to flip backLeetCode ↗
56 / 75·StringEasy

Valid Palindrome

Given a string s, return true if it is a palindrome considering only alphanumeric characters and ignoring case.

Input
s = "A man, a plan, a canal: Panama"
Output
true
Tap to reveal solutionLeetCode ↗
Solution · Java·StringEasy

Valid Palindrome

class Solution {
    public boolean isPalindrome(String s) {
        int l = 0, r = s.length() - 1;
        while (l < r) {
            while (l < r && !Character.isLetterOrDigit(s.charAt(l))) l++;
            while (l < r && !Character.isLetterOrDigit(s.charAt(r))) r--;
            if (Character.toLowerCase(s.charAt(l)) != Character.toLowerCase(s.charAt(r)))
                return false;
            l++; r--;
        }
        return true;
    }
}
← Tap card to flip backLeetCode ↗
57 / 75·StringMedium

Longest Palindromic Substring

Given a string s, return the longest palindromic substring. Expand around each center (odd and even).

Input
s = "babad"
Output
"bab" or "aba"
Tap to reveal solutionLeetCode ↗
Solution · Java·StringMedium

Longest Palindromic Substring

class Solution {
    int start = 0, maxLen = 0;
    public String longestPalindrome(String s) {
        for (int i = 0; i < s.length(); i++) {
            expand(s, i, i);
            expand(s, i, i + 1);
        }
        return s.substring(start, start + maxLen);
    }
    private void expand(String s, int l, int r) {
        while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) { l--; r++; }
        if (r - l - 1 > maxLen) { maxLen = r - l - 1; start = l + 1; }
    }
}
← Tap card to flip backLeetCode ↗
58 / 75·StringMedium

Palindromic Substrings

Given a string s, return the number of palindromic substrings in it. Expand around centers and count.

Input
s = "aaa"
Output
6
Tap to reveal solutionLeetCode ↗
Solution · Java·StringMedium

Palindromic Substrings

class Solution {
    int count = 0;
    public int countSubstrings(String s) {
        for (int i = 0; i < s.length(); i++) {
            expand(s, i, i);
            expand(s, i, i + 1);
        }
        return count;
    }
    private void expand(String s, int l, int r) {
        while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) {
            count++; l--; r++;
        }
    }
}
← Tap card to flip backLeetCode ↗
59 / 75·StringMedium

Encode and Decode Strings

Design an algorithm to encode a list of strings to one string and decode it back. Length-prefix each string with a delimiter, e.g. '5#hello'.

Input
["lint","code","love","you"]
Output
"4#lint4#code4#love3#you"
Tap to reveal solutionLeetCode ↗
Solution · Java·StringMedium

Encode and Decode Strings

public class Codec {
    public String encode(List<String> strs) {
        StringBuilder sb = new StringBuilder();
        for (String s : strs) sb.append(s.length()).append('#').append(s);
        return sb.toString();
    }
    public List<String> decode(String s) {
        List<String> res = new ArrayList<>();
        int i = 0;
        while (i < s.length()) {
            int j = i;
            while (s.charAt(j) != '#') j++;
            int len = Integer.parseInt(s.substring(i, j));
            res.add(s.substring(j + 1, j + 1 + len));
            i = j + 1 + len;
        }
        return res;
    }
}
← Tap card to flip backLeetCode ↗
60 / 75·TreeEasy

Maximum Depth of Binary Tree

Given the root of a binary tree, return its maximum depth.

Input
root = [3,9,20,null,null,15,7]
Output
3
Tap to reveal solutionLeetCode ↗
Solution · Java·TreeEasy

Maximum Depth of Binary Tree

class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) return 0;
        return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
    }
}
← Tap card to flip backLeetCode ↗
61 / 75·TreeEasy

Same Tree

Given the roots of two binary trees p and q, return true if they are structurally identical and the nodes have the same values.

Input
p = [1,2,3], q = [1,2,3]
Output
true
Tap to reveal solutionLeetCode ↗
Solution · Java·TreeEasy

Same Tree

class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null && q == null) return true;
        if (p == null || q == null || p.val != q.val) return false;
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }
}
← Tap card to flip backLeetCode ↗
62 / 75·TreeEasy

Invert Binary Tree

Given the root of a binary tree, invert the tree (mirror it) and return its root.

Input
[4,2,7,1,3,6,9]
Output
[4,7,2,9,6,3,1]
Tap to reveal solutionLeetCode ↗
Solution · Java·TreeEasy

Invert Binary Tree

class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) return null;
        TreeNode left = invertTree(root.right);
        TreeNode right = invertTree(root.left);
        root.left = left;
        root.right = right;
        return root;
    }
}
← Tap card to flip backLeetCode ↗
63 / 75·TreeHard

Binary Tree Maximum Path Sum

A path is any sequence of nodes connected by edges. Return the maximum sum of any non-empty path. Track best at each node; return 'gain' upward.

Input
root = [-10,9,20,null,null,15,7]
Output
42
Tap to reveal solutionLeetCode ↗
Solution · Java·TreeHard

Binary Tree Maximum Path Sum

class Solution {
    int best = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        dfs(root);
        return best;
    }
    private int dfs(TreeNode n) {
        if (n == null) return 0;
        int l = Math.max(0, dfs(n.left));
        int r = Math.max(0, dfs(n.right));
        best = Math.max(best, n.val + l + r);
        return n.val + Math.max(l, r);
    }
}
← Tap card to flip backLeetCode ↗
64 / 75·TreeMedium

Binary Tree Level Order Traversal

Given the root of a binary tree, return the level order traversal of its nodes' values (BFS).

Input
root = [3,9,20,null,null,15,7]
Output
[[3],[9,20],[15,7]]
Tap to reveal solutionLeetCode ↗
Solution · Java·TreeMedium

Binary Tree Level Order Traversal

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        if (root == null) return res;
        Queue<TreeNode> q = new ArrayDeque<>();
        q.offer(root);
        while (!q.isEmpty()) {
            int len = q.size();
            List<Integer> level = new ArrayList<>();
            for (int i = 0; i < len; i++) {
                TreeNode n = q.poll();
                level.add(n.val);
                if (n.left != null) q.offer(n.left);
                if (n.right != null) q.offer(n.right);
            }
            res.add(level);
        }
        return res;
    }
}
← Tap card to flip backLeetCode ↗
65 / 75·TreeHard

Serialize and Deserialize Binary Tree

Design an algorithm to serialize a binary tree to a string and deserialize it back. Preorder DFS with '#' for null works well.

Input
root = [1,2,3,null,null,4,5]
Output
"1,2,#,#,3,4,#,#,5,#,#"
Tap to reveal solutionLeetCode ↗
Solution · Java·TreeHard

Serialize and Deserialize Binary Tree

public class Codec {
    public String serialize(TreeNode root) {
        StringBuilder sb = new StringBuilder();
        build(root, sb);
        return sb.toString();
    }
    private void build(TreeNode n, StringBuilder sb) {
        if (n == null) { sb.append("#,"); return; }
        sb.append(n.val).append(',');
        build(n.left, sb);
        build(n.right, sb);
    }
    public TreeNode deserialize(String data) {
        Queue<String> q = new ArrayDeque<>(Arrays.asList(data.split(",")));
        return parse(q);
    }
    private TreeNode parse(Queue<String> q) {
        String v = q.poll();
        if (v.equals("#")) return null;
        TreeNode n = new TreeNode(Integer.parseInt(v));
        n.left = parse(q);
        n.right = parse(q);
        return n;
    }
}
← Tap card to flip backLeetCode ↗
66 / 75·TreeEasy

Subtree of Another Tree

Given roots root and subRoot, return true if subRoot has the same structure & values as some subtree of root.

Input
root = [3,4,5,1,2], subRoot = [4,1,2]
Output
true
Tap to reveal solutionLeetCode ↗
Solution · Java·TreeEasy

Subtree of Another Tree

class Solution {
    public boolean isSubtree(TreeNode root, TreeNode sub) {
        if (root == null) return false;
        if (same(root, sub)) return true;
        return isSubtree(root.left, sub) || isSubtree(root.right, sub);
    }
    private boolean same(TreeNode a, TreeNode b) {
        if (a == null && b == null) return true;
        if (a == null || b == null || a.val != b.val) return false;
        return same(a.left, b.left) && same(a.right, b.right);
    }
}
← Tap card to flip backLeetCode ↗
67 / 75·TreeMedium

Construct Tree from Preorder & Inorder

Given preorder and inorder traversals of a binary tree (with unique values), reconstruct and return the tree. preorder[0] is the root; locate it in inorder to split left/right.

Input
preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output
[3,9,20,null,null,15,7]
Tap to reveal solutionLeetCode ↗
Solution · Java·TreeMedium

Construct Tree from Preorder & Inorder

class Solution {
    int p = 0;
    Map<Integer, Integer> idx = new HashMap<>();
    int[] preorder;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        this.preorder = preorder;
        for (int i = 0; i < inorder.length; i++) idx.put(inorder[i], i);
        return build(0, inorder.length - 1);
    }
    private TreeNode build(int l, int r) {
        if (l > r) return null;
        int val = preorder[p++];
        TreeNode node = new TreeNode(val);
        int m = idx.get(val);
        node.left = build(l, m - 1);
        node.right = build(m + 1, r);
        return node;
    }
}
← Tap card to flip backLeetCode ↗
68 / 75·TreeMedium

Validate Binary Search Tree

Given the root of a binary tree, determine if it is a valid BST. Pass an open (lo, hi) range down recursively.

Input
root = [2,1,3]
Output
true
Tap to reveal solutionLeetCode ↗
Solution · Java·TreeMedium

Validate Binary Search Tree

class Solution {
    public boolean isValidBST(TreeNode root) {
        return check(root, null, null);
    }
    private boolean check(TreeNode n, Integer lo, Integer hi) {
        if (n == null) return true;
        if (lo != null && n.val <= lo) return false;
        if (hi != null && n.val >= hi) return false;
        return check(n.left, lo, n.val) && check(n.right, n.val, hi);
    }
}
← Tap card to flip backLeetCode ↗
69 / 75·TreeMedium

Kth Smallest Element in a BST

Given the root of a BST and an integer k, return the kth smallest value (1-indexed). Iterative inorder traversal.

Input
root = [3,1,4,null,2], k = 1
Output
1
Tap to reveal solutionLeetCode ↗
Solution · Java·TreeMedium

Kth Smallest Element in a BST

class Solution {
    public int kthSmallest(TreeNode root, int k) {
        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();
            if (--k == 0) return curr.val;
            curr = curr.right;
        }
        return -1;
    }
}
← Tap card to flip backLeetCode ↗
70 / 75·TreeMedium

Lowest Common Ancestor of BST

Given a BST and two nodes p and q, return their lowest common ancestor. Walk down: when p and q split, that node is the LCA.

Input
root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
Output
6
Tap to reveal solutionLeetCode ↗
Solution · Java·TreeMedium

Lowest Common Ancestor of BST

class 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;
    }
}
← Tap card to flip backLeetCode ↗
71 / 75·TreeMedium

Implement Trie (Prefix Tree)

Implement a Trie with insert(word), search(word), and startsWith(prefix) operations.

Input
insert("apple"), search("apple"), search("app"), startsWith("app")
Output
true, false, true
Tap to reveal solutionLeetCode ↗
Solution · Java·TreeMedium

Implement Trie (Prefix Tree)

class Trie {
    static class Node { Node[] kids = new Node[26]; boolean end; }
    private final Node root = new Node();
    public void insert(String word) {
        Node n = root;
        for (char c : word.toCharArray()) {
            int i = c - 'a';
            if (n.kids[i] == null) n.kids[i] = new Node();
            n = n.kids[i];
        }
        n.end = true;
    }
    public boolean search(String word) {
        Node n = find(word);
        return n != null && n.end;
    }
    public boolean startsWith(String prefix) { return find(prefix) != null; }
    private Node find(String s) {
        Node n = root;
        for (char c : s.toCharArray()) {
            int i = c - 'a';
            if (n.kids[i] == null) return null;
            n = n.kids[i];
        }
        return n;
    }
}
← Tap card to flip backLeetCode ↗
72 / 75·TreeMedium

Add and Search Word

Design WordDictionary supporting addWord and search where '.' matches any letter. DFS over a Trie when '.' is encountered.

Input
add "bad","dad","mad", search "pad","bad",".ad","b.."
Output
false, true, true, true
Tap to reveal solutionLeetCode ↗
Solution · Java·TreeMedium

Add and Search Word

class WordDictionary {
    static class Node { Node[] kids = new Node[26]; boolean end; }
    private final Node root = new Node();
    public void addWord(String word) {
        Node n = root;
        for (char c : word.toCharArray()) {
            int i = c - 'a';
            if (n.kids[i] == null) n.kids[i] = new Node();
            n = n.kids[i];
        }
        n.end = true;
    }
    public boolean search(String word) { return dfs(root, word, 0); }
    private boolean dfs(Node n, String w, int i) {
        if (n == null) return false;
        if (i == w.length()) return n.end;
        char c = w.charAt(i);
        if (c == '.') {
            for (Node k : n.kids) if (dfs(k, w, i + 1)) return true;
            return false;
        }
        return dfs(n.kids[c - 'a'], w, i + 1);
    }
}
← Tap card to flip backLeetCode ↗
73 / 75·TreeHard

Word Search II

Given a board of letters and a list of words, return all words that can be formed in the board. Build a Trie of the words and DFS once.

Input
board, words = ["oath","pea","eat","rain"]
Output
["eat","oath"]
Tap to reveal solutionLeetCode ↗
Solution · Java·TreeHard

Word Search II

class Solution {
    static class Node { Node[] kids = new Node[26]; String word; }
    public List<String> findWords(char[][] board, String[] words) {
        Node root = new Node();
        for (String w : words) {
            Node n = root;
            for (char c : w.toCharArray()) {
                int i = c - 'a';
                if (n.kids[i] == null) n.kids[i] = new Node();
                n = n.kids[i];
            }
            n.word = w;
        }
        List<String> res = new ArrayList<>();
        for (int i = 0; i < board.length; i++)
            for (int j = 0; j < board[0].length; j++)
                dfs(board, i, j, root, res);
        return res;
    }
    private void dfs(char[][] b, int r, int c, Node node, List<String> res) {
        char ch = b[r][c];
        if (ch == '#' || node.kids[ch - 'a'] == null) return;
        node = node.kids[ch - 'a'];
        if (node.word != null) { res.add(node.word); node.word = null; }
        b[r][c] = '#';
        if (r > 0) dfs(b, r - 1, c, node, res);
        if (r < b.length - 1) dfs(b, r + 1, c, node, res);
        if (c > 0) dfs(b, r, c - 1, node, res);
        if (c < b[0].length - 1) dfs(b, r, c + 1, node, res);
        b[r][c] = ch;
    }
}
← Tap card to flip backLeetCode ↗
74 / 75·HeapMedium

Top K Frequent Elements

Given nums and integer k, return the k most frequent elements. Bucket sort by frequency for O(n).

Input
nums = [1,1,1,2,2,3], k = 2
Output
[1,2]
Tap to reveal solutionLeetCode ↗
Solution · Java·HeapMedium

Top K Frequent Elements

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> freq = new HashMap<>();
        for (int n : nums) freq.merge(n, 1, Integer::sum);
        List<List<Integer>> buckets = new ArrayList<>();
        for (int i = 0; i <= nums.length; i++) buckets.add(new ArrayList<>());
        for (Map.Entry<Integer, Integer> e : freq.entrySet())
            buckets.get(e.getValue()).add(e.getKey());
        int[] res = new int[k];
        int idx = 0;
        for (int i = buckets.size() - 1; i >= 0 && idx < k; i--)
            for (int n : buckets.get(i)) {
                res[idx++] = n;
                if (idx == k) break;
            }
        return res;
    }
}
← Tap card to flip backLeetCode ↗
75 / 75·HeapHard

Find Median from Data Stream

Design MedianFinder with addNum(num) and findMedian(). Maintain a max-heap (lower half) and min-heap (upper half), kept balanced.

Input
addNum(1), addNum(2), findMedian(), addNum(3), findMedian()
Output
1.5, 2
Tap to reveal solutionLeetCode ↗
Solution · Java·HeapHard

Find Median from Data Stream

class MedianFinder {
    private final PriorityQueue<Integer> lo = new PriorityQueue<>(Collections.reverseOrder());
    private final PriorityQueue<Integer> hi = new PriorityQueue<>();
    public void addNum(int num) {
        lo.offer(num);
        hi.offer(lo.poll());
        if (hi.size() > lo.size()) lo.offer(hi.poll());
    }
    public double findMedian() {
        return lo.size() > hi.size() ? lo.peek() : (lo.peek() + hi.peek()) / 2.0;
    }
}
← Tap card to flip backLeetCode ↗