Leetcode刷题面试2025

devtools/2025/2/20 14:31:30/

文章目录

      • 排序算法
      • 动态规划
      • 回溯算法
      • 贪心算法
      • 位运算
      • 数学题
      • 二分查找
      • 数组
      • 链表
      • 队列
      • 双指针
      • 哈希表
      • 前缀和
      • 二叉树

以下是为你整理的上述 LeetCode 题目对应的链接:

排序算法

  • 插入排序
public class InsertionSort {public static void insertionSort(int[] arr) {int n = arr.length;for (int i = 1; i < n; i++) {int key = arr[i]; // 当前需要插入的元素int j = i - 1;// 将比 key 大的元素向后移动while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j--;}arr[j + 1] = key; // 插入 key 到正确位置}}public static void main(String[] args) {int[] arr = {12, 11, 13, 5, 6};insertionSort(arr);System.out.println("排序后的数组:");for (int i : arr) {System.out.print(i + " ");}}
}
  • 冒泡排序
public class BubbleSort {public static void bubbleSort(int[] arr) {int n = arr.length;boolean swapped;for (int i = 0; i < n - 1; i++) {swapped = false;for (int j = 0; j < n - 1 - i; j++) {if (arr[j] > arr[j + 1]) {// 交换 arr[j] 和 arr[j+1]int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;swapped = true;}}// 如果没有发生交换,说明数组已经有序,提前退出if (!swapped) {break;}}}public static void main(String[] args) {int[] arr = {64, 34, 25, 12, 22, 11, 90};bubbleSort(arr);System.out.println("排序后的数组:");for (int i : arr) {System.out.print(i + " ");}}
}
  • 快速排序
public class QuickSort {public static void quickSort(int[] arr, int low, int high) {if (low < high) {// 找到分区点,将数组分为两部分int pi = partition(arr, low, high);// 递归排序左半部分quickSort(arr, low, pi - 1);// 递归排序右半部分quickSort(arr, pi + 1, high);}}// 分区函数private static int partition(int[] arr, int low, int high) {int pivot = arr[high]; // 选择最后一个元素作为基准int i = low - 1; // i 是较小元素的索引for (int j = low; j < high; j++) {// 如果当前元素小于或等于基准if (arr[j] <= pivot) {i++;// 交换 arr[i] 和 arr[j]int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}// 将基准元素放到正确的位置int temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;return i + 1; // 返回基准元素的索引}public static void main(String[] args) {int[] arr = {10, 7, 8, 9, 1, 5};quickSort(arr, 0, arr.length - 1);System.out.println("排序后的数组:");for (int i : arr) {System.out.print(i + " ");}}
}
  • 堆排序
public class HeapSort {public static void heapSort(int[] arr) {int n = arr.length;// 构建最大堆(从最后一个非叶子节点开始)for (int i = n / 2 - 1; i >= 0; i--) {heapify(arr, n, i);}// 逐个提取堆顶元素(最大值),放到数组末尾for (int i = n - 1; i > 0; i--) {// 将堆顶元素(最大值)与当前末尾元素交换int temp = arr[0];arr[0] = arr[i];arr[i] = temp;// 重新调整堆,使其满足最大堆性质heapify(arr, i, 0);}}// 堆化函数:调整以 i 为根的子树为最大堆private static void heapify(int[] arr, int n, int i) {int largest = i; // 初始化最大值为根节点int left = 2 * i + 1; // 左子节点int right = 2 * i + 2; // 右子节点// 如果左子节点比根节点大,更新最大值if (left < n && arr[left] > arr[largest]) {largest = left;}// 如果右子节点比当前最大值大,更新最大值if (right < n && arr[right] > arr[largest]) {largest = right;}// 如果最大值不是根节点,交换并递归调整if (largest != i) {int temp = arr[i];arr[i] = arr[largest];arr[largest] = temp;// 递归调整受影响的子树heapify(arr, n, largest);}}public static void main(String[] args) {int[] arr = {12, 11, 13, 5, 6, 7};heapSort(arr);System.out.println("排序后的数组:");for (int i : arr) {System.out.print(i + " ");}}
}
  • 计数排序
public class CountingSort { public static void countingSort(int[] arr) { if (arr == null || arr.length  <= 1) { return; } // 找出数组中的最大值 int max = arr[0]; for (int num : arr) { if (num > max) { max = num; } } // 定义计数数组,长度为最大值 + 1 int[] count = new int[max + 1]; // 统计每个元素出现的次数 for (int num : arr) { count[num]++; } // 遍历计数数组,将元素按顺序放回原数组 int index = 0; for (int i = 0; i < count.length;  i++) { while (count[i] > 0) { arr[index++] = i; count[i]--; } } } public static void main(String[] args) { int[] arr = {4, 2, 2, 8, 3, 3, 1}; System.out.println(" 排序前:"); for (int num : arr) { System.out.print(num  + " "); } // 调用计数排序方法 countingSort(arr); System.out.println("\n 排序后:"); for (int num : arr) { System.out.print(num  + " "); } } 
} 
  • 桶排序
import java.util.ArrayList;  
import java.util.Collections;  
import java.util.List;  public class BucketSort { public static double[] bucketSort(double[] array) { if (array == null || array.length  == 0) { return array; } // 找出数组中的最大值和最小值 double max = array[0]; double min = array[0]; for (double num : array) { if (num > max) { max = num; } if (num < min) { min = num; } } // 计算桶的数量 int bucketNum = array.length;  List<List<Double>> buckets = new ArrayList<>(); for (int i = 0; i < bucketNum; i++) { buckets.add(new  ArrayList<>()); } // 将元素分配到不同的桶中 for (double num : array) { int bucketIndex = (int) ((num - min) * (bucketNum - 1) / (max - min)); buckets.get(bucketIndex).add(num);  } // 对每个桶内的元素进行排序 for (List<Double> bucket : buckets) { Collections.sort(bucket);  } // 将所有桶中的元素合并到一个数组中 double[] sortedArray = new double[array.length]; int index = 0; for (List<Double> bucket : buckets) { for (double num : bucket) { sortedArray[index++] = num; } } return sortedArray; } public static void main(String[] args) { double[] array = {0.42, 0.32, 0.33, 0.52, 0.37, 0.47, 0.51}; double[] sortedArray = bucketSort(array); for (double num : sortedArray) { System.out.print(num  + " "); } } 
} 

动态规划

  • 爬楼梯(LeetCode 70)
    public int climbStairs(int n) {if (n <= 2) {return n;}int first = 1;int second = 2;int result = 0;for (int i = 3; i <= n; i++) {result = first + second;first = second;second = result;}return result;}
}
  • 零钱兑换(LeetCode 322)
    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];}
  • 买卖股票的最佳时机(LeetCode 121)
    public int maxProfit(int[] prices) {int minPrice = Integer.MAX_VALUE;int maxProfit = 0;for (int price : prices) {if (price < minPrice) {minPrice = price;} else if (price - minPrice > maxProfit) {maxProfit = price - minPrice;}}return maxProfit;}
  • 买卖股票的最佳时机 II(LeetCode 122)
   public int maxProfit(int[] prices) {int profit = 0;for (int i = 1; i < prices.length; i++) {int pr = prices[i] - prices[i - 1]if (pr > 0) {profit += pr;}}return profit;}
  • 最长上升子序列(LeetCode 300)
    public int lengthOfLIS(int[] nums) {if (nums == null || nums.length == 0) {return 0;}int[] dp = new int[nums.length];Arrays.fill(dp, 1);int max = 1;for (int i = 1; i < nums.length; i++) {for (int j = 0; j < i; j++) {if (nums[j] < nums[i]) {dp[i] = Math.max(dp[i], dp[j] + 1);}max = Math.max(max, dp[i]);}}return max;}
  • 不同路径(LeetCode 62)
    public int uniquePaths(int m, int n) {int[][] dp = new int[m][n];for (int i = 0; i < m; i++) {dp[i][0] = 1;}for (int i = 0; i < n; i++) {dp[0][i] = 1;}for (int i = 1; i < m; i++) {for (int j = 1; j < n; j++) {dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}return dp[m - 1][n - 1];}
  • 最小路径和(LeetCode 64)
    public int minPathSum(int[][] grid) {int m = grid.length;int n = grid[0].length;int[][] dp = new int[m][n];dp[0][0] = grid[0][0];for (int i = 1; i < n; i++) {dp[0][i] = dp[0][i - 1] + grid[0][i];}for (int i = 1; i < m; i++) {dp[i][0] = dp[i - 1][0] + grid[i][0]; }for (int i = 1; i < m; i++) {for(int j = 1; j < n; j++) {dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1]) + grid[i][j];}}return dp[m - 1][n - 1];}
  • 打家劫舍(LeetCode 198)
    public int rob(int[] nums) {int n = nums.length;if (n == 0) return 0;if (n == 1) return nums[0];int[] dp = new int[n];dp[0] = nums[0];dp[1] = Math.max(nums[0], nums[1]);for (int i = 2; i < n; i++) {dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i]);}return dp[n - 1];}
  • 打家劫舍 II(LeetCode 213)
    public int rob(int[] nums) {int n = nums.length;if (n == 0) {return 0;}if (n == 1) {return nums[0];}// Case 1: Rob houses from the first to the second - last houseint result1 = robRange(nums, 0, n - 2);// Case 2: Rob houses from the second to the last houseint result2 = robRange(nums, 1, n - 1);// Return the maximum of the two resultsreturn Math.max(result1, result2);}private int robRange(int[] nums, int start, int end) {if (start == end) {return nums[start];}int n = end - start + 1;int[] dp = new int[n];dp[0] = nums[start];dp[1] = Math.max(nums[start], nums[start + 1]);for (int i = 2; i < n; i++) {dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[start + i]);}return dp[n - 1];}
  • 零钱兑换 II(LeetCode 518)
   public int change(int amount, int[] coins) {// Create a dp array to store the number of combinations for each amountint[] dp = new int[amount + 1];// Initialize dp[0] to 1, as there is one way to make up amount 0 (using no coins)dp[0] = 1;// Iterate through each coin denominationfor (int coin : coins) {// Update the dp array for each amount from coin to the target amountfor (int i = coin; i <= amount; i++) {// The number of combinations to make up amount i is the sum of the original number of combinations// and the number of combinations to make up amount i - coindp[i] += dp[i - coin];}}// Return the number of combinations to make up the target amountreturn dp[amount];}

回溯算法

  • N 皇后(LeetCode 51)
    private List<List<String>> result = new ArrayList<>();private int n;public List<List<String>> solveNQueens(int n) {this.n = n;char[][] board = new char[n][n];// Initialize the chessboardfor (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {board[i][j] = '.';}}backtrack(board, 0);return result;}private void backtrack(char[][] board, int row) {if (row == n) {result.add(constructSolution(board));return;}for (int col = 0; col < n; col++) {if (isValid(board, row, col)) {board[row][col] = 'Q';backtrack(board, row + 1);board[row][col] = '.';}}}private boolean isValid(char[][] board, int row, int col) {// Check the columnfor (int i = 0; i < row; i++) {if (board[i][col] == 'Q') {return false;}}// Check the upper - left diagonalfor (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {if (board[i][j] == 'Q') {return false;}}// Check the upper - right diagonalfor (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {if (board[i][j] == 'Q') {return false;}}return true;}private List<String> constructSolution(char[][] board) {List<String> solution = new ArrayList<>();for (int i = 0; i < n; i++) {solution.add(new String(board[i]));}return solution;}
  • 子集(LeetCode 78)
    public List<List<Integer>> subsets(int[] nums) {List<List<Integer>> result = new ArrayList<>();track(result, new ArrayList<Integer>(), nums, 0);return result;}private void track(List<List<Integer>> result, List<Integer> tempList, int[] nums, int start) {result.add(new ArrayList<>(tempList));for (int i = start; i < nums.length; i++) {tempList.add(nums[i]);track(result, tempList, nums, i + 1);tempList.remove(tempList.size() - 1);}}
  • 全排列(LeetCode 46)
    List<List<Integer>> result;List<Integer> list;boolean[] used;int[] nums;public List<List<Integer>> permute(int[] nums) {this.result = new ArrayList<>();this.used = new boolean[nums.length];this.list = new ArrayList<>();this.nums = nums;track();return result;}private void track() {if (list.size() == nums.length) {result.add(new ArrayList<>(list));return;}for (int i = 0; i < nums.length; i++) {if (used[i]) {continue;}used[i] = true;list.add(nums[i]);track();used[i] = false;list.remove(list.size() - 1);}}
  • 组合(LeetCode 77)
    private List<List<Integer>> result;private List<Integer> temp;private int n;private int k;public List<List<Integer>> combine(int n, int k) {this.result = new ArrayList<>();this.temp = new ArrayList<>();this.n = n;this.k = k;track(1);return result;}private void track(int start) {if (temp.size() == k) {result.add(new ArrayList<>(temp));return;}for (int i = start; i <=n; i++) {temp.add(i);track(i+1);temp.remove(temp.size() - 1);}}
  • 电话号码的字母组合(LeetCode 17)
    private static final String[] PHONE_MAP = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};private List<String> result;private StringBuilder sb;private String digits;public List<String> letterCombinations(String digits) {this.result = new ArrayList<>();this.sb = new StringBuilder();this.digits = digits;if (digits == null || digits.length() == 0) {return result;}track(0);return result;}private void track(int index) {if (index == digits.length()) {result.add(sb.toString());return;}int digit = digits.charAt(index) - '0';String letters = PHONE_MAP[digit];for (int i = 0; i < letters.length(); i++) {sb.append(letters.charAt(i));track(index+1);sb.deleteCharAt(sb.length() - 1);}}
  • 单词搜索(LeetCode 79)
    private boolean[][] visited;private int rows, cols;public boolean exist(char[][] board, String word) {rows = board.length;cols = board[0].length;visited = new boolean[rows][cols];for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {if (board[i][j] == word.charAt(0) && backtrack(board, word, i, j, 0)) {return true;}}}return false;}private boolean backtrack(char[][] board, String word, int i, int j, int index) {if (index == word.length()) {return true;}if (i < 0 || i >= rows || j < 0 || j >= cols || visited[i][j] || board[i][j] != word.charAt(index)) {return false;}visited[i][j] = true;boolean found = backtrack(board, word, i + 1, j, index + 1) ||backtrack(board, word, i - 1, j, index + 1) ||backtrack(board, word, i, j + 1, index + 1) ||backtrack(board, word, i, j - 1, index + 1);visited[i][j] = false;return found;}
  • 组合总和(LeetCode 39)
    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> tempList, int[] candidates, int remain, int start) {if (remain < 0) {return;} else if (remain == 0) {result.add(new ArrayList<>(tempList));} else {for (int i = start; i < candidates.length; i++) {tempList.add(candidates[i]);backtrack(result, tempList, candidates, remain - candidates[i], i);tempList.remove(tempList.size() - 1);}}}
  • 组合总和 II(LeetCode 40)
    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> tempList, int[] candidates, int remain, int start) {if (remain < 0) {return;} else if (remain == 0) {result.add(new ArrayList<>(tempList));} else {for (int i = start; i < candidates.length; i++) {// Skip duplicatesif (i > start && candidates[i] == candidates[i - 1]) {continue;}tempList.add(candidates[i]);backtrack(result, tempList, candidates, remain - candidates[i], i + 1);tempList.remove(tempList.size() - 1);}}}

贪心算法

  • 分发饼干(LeetCode 455)
    public int findContentChildren(int[] g, int[] s) {Arrays.sort(g);Arrays.sort(s);int nums = 0;int i = 0; int j = 0;while(i < g.length && j < s.length) {if (s[j] >= g[i]) {nums++;i++;}j++;}return nums;}
  • 柠檬水找零(LeetCode 860)
    public boolean lemonadeChange(int[] bills) {int five = 0, ten = 0;for (int bill: bills) {switch(bill) {case 5:five++;break;case 10:if(five == 0) {return false;}five--;ten++;break;case 20:if(five>0&&ten>0) {five--;ten--;} else if(five >= 3) {five -= 3;} else {return false;}break;}}return true;}
  • 最大子序和(LeetCode 53)
    public int maxSubArray(int[] nums) {int maxSoFar = nums[0];int maxEndHere = nums[0];for (int i = 1; i < nums.length; i++) {maxEndHere = Math.max(nums[i], maxEndHere + nums[i]);maxSoFar = Math.max(maxSoFar, maxEndHere);}return maxSoFar;}
  • 买卖股票的最佳时机(LeetCode 121)
    public int maxProfit(int[] prices) {int minPrice = Integer.MAX_VALUE;int maxProfit = 0;for (int price : prices) {if (price < minPrice) {minPrice = price;} else if (price - minPrice > maxProfit) {maxProfit = price - minPrice;}}return maxProfit;}
  • 跳跃游戏(LeetCode 55)
    public boolean canJump(int[] nums) {int lastPos = nums.length - 1;for (int i = nums.length - 1; i >= 0; i--) {if (i + nums[i] >= lastPos) {lastPos = i;}}return lastPos == 0;}
  • 加油站(LeetCode 134)
    public int canCompleteCircuit(int[] gas, int[] cost) {int total = 0;int current = 0;int start = 0;for (int i = 0; i < gas.length; i++) {total += gas[i] - cost[i];current += gas[i] - cost[i];if (current < 0) {start = i + 1;current = 0;}}return total >= 0 ? start : -1;}
  • 种花问题(LeetCode 605)
    public boolean canPlaceFlowers(int[] flowerbed, int n) {int count = 0;for (int i = 0; i < flowerbed.length; i++) {if (flowerbed[i] == 0&& (i == 0 || flowerbed[i - 1] == 0)&& (i == flowerbed.length - 1 || flowerbed[i+1] == 0)) {flowerbed[i] = 1;count++;}}return count >= n;}

位运算

  • 只出现一次的数字(LeetCode 136)
    public int singleNumber(int[] nums) {int result = 0;for (int num: nums) {result ^= num;}return result;}
  • 只出现一次的数字 II(LeetCode 137)
    public int singleNumber(int[] nums) {int ones = 0, twos = 0;for (int num : nums) {ones = (ones ^ num) & ~twos;twos = (twos ^ num) & ~ones;}return ones;}
  • 只出现一次的数字 III(LeetCode 260)
    public int[] singleNumber(int[] nums) {// 第一步:对所有数字进行异或int xorResult = 0;for (int num : nums) {xorResult ^= num;  // xorResult 最终得到的是两个只出现一次的数字的异或结果}// 第二步:找到 xorResult 中最右边的 1int rightmostOne = xorResult & (-xorResult);  // 第三步:根据这个位将数组分成两组int x = 0;for (int num : nums) {if ((num & rightmostOne) != 0) {  // 如果当前数字在这个位上是 1x ^= num;  // 将其归入第一组并异或}}// 第四步:得到另一个数int y = xorResult ^ x;  // 用总异或结果异或第一个数,得到第二个数return new int[]{x, y};}
  • 汉明距离(LeetCode 461)
    public int hammingDistance(int x, int y) {int xor = x ^ y;int distance = 0;while(xor != 0) {distance += xor & 1;xor >>= 1;}return distance;}
  • 丢失的数字(LeetCode 268)
    public int missingNumber(int[] nums) {int xor = 0;for (int i = 0; i <= nums.length; i++) {xor ^= i;}for(int n : nums) {xor ^= n;}return xor;}

数学题

  • Pow(x, n)(LeetCode 50)
    public double myPow(double x, int n) {long N = n;return N >= 0 ? quickPow(x, N) : 1.0 / quickPow(x, -N);}private double quickPow(double x, long n) {double ans = 1.0;double current = x;while (n > 0) {if (n % 2 == 1) {ans *= current;}current *= current;n /= 2;}return ans;}
  • 字符串相乘(LeetCode 43)
    public String multiply(String num1, String num2) {if (num1.equals("0") || num2.equals("0")) {return "0";}int m = num1.length();int 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;int p2 = i + j + 1;// 加上之前的进位int total = mul + result[p2];// 更新结果数组result[p2] = total % 10;result[p1] += total / 10;}}StringBuilder sb = new StringBuilder();// 处理前导零for (int num : result) {if (!(sb.length() == 0 && num == 0)) {sb.append(num);}}return sb.toString();}
  • 寻找两个正序数组的中位数(LeetCode 4)
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {if (nums1.length > nums2.length) {int[] temp = nums1;nums1 = nums2;nums2 = temp;}int m = nums1.length;int n = nums2.length;int imin = 0, imax = m, halfLen = (m + n + 1) / 2;while (imin <= imax) {int i = (imin + imax) / 2;int j = halfLen - i;if (i < m && nums2[j - 1] > nums1[i]) {// i 太小,需要增大imin = i + 1;} else if (i > 0 && nums1[i - 1] > nums2[j]) {// i 太大,需要减小imax = i - 1;} else {// i 是完美的分割点int maxOfLeft;if (i == 0) {maxOfLeft = nums2[j - 1];} else if (j == 0) {maxOfLeft = nums1[i - 1];} else {maxOfLeft = Math.max(nums1[i - 1], nums2[j - 1]);}if ((m + n) % 2 == 1) {return maxOfLeft;}int minOfRight;if (i == m) {minOfRight = nums2[j];} else if (j == n) {minOfRight = nums1[i];} else {minOfRight = Math.min(nums1[i], nums2[j]);}return (maxOfLeft + minOfRight) / 2.0;}}return 0.0;}
  • 整数反转(LeetCode 7)
    public int reverse(int x) {int sign = x < 0 ? -1 : 1;x = Math.abs(x);int result = 0;while (x != 0) {int digit = x % 10;x /= 10;// 检查是否溢出if (result > (Integer.MAX_VALUE - digit) / 10) {return 0;}result = result * 10 + digit;}result *= sign;return result;}
  • 最大公约数(LeetCode 1071)
    public String gcdOfStrings(String str1, String str2) {int gcdLength = gcd(str1.length(), str2.length());for (int length = gcdLength; length > 0; length--) {if (gcdLength % length == 0) {String candidate = str1.substring(0, length);if (repeatString(candidate, str1.length() / length).equals(str1) && repeatString(candidate, str2.length() / length).equals(str2)) {return candidate;}}}return "";}// 求最大公约数private int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);}// 重复字符串private String repeatString(String s, int n) {StringBuilder sb = new StringBuilder();for (int i = 0; i < n; i++) {sb.append(s);}return sb.toString();}

二分查找

  • 第一个错误的版本(LeetCode 278)
    public int firstBadVersion(int n) {int left = 1;  // 定义左边界为 1int right = n;  // 定义右边界为 nwhile (left < right) {  // 当左边界小于右边界时,进行二分查找int mid = left + (right - left) / 2;  // 计算中间位置if (isBadVersion(mid)) {  // 如果中间位置是坏版本right = mid;  // 将右边界更新为中间位置} else {  // 如果中间位置不是坏版本left = mid + 1;  // 将左边界更新为中间位置的下一个}}return left;  // 返回最终的左边界,即为第一个坏版本}
  • 搜索插入位置(LeetCode 35)
    public int searchInsert(int[] nums, int target) {int left = 0;int 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;}
  • 寻找峰值(LeetCode 162)
    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]) {right = mid;} else {left = mid + 1;}}return left;}
  • 寻找两个正序数组的中位数(LeetCode 4)
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {int m = nums1.length;int n = nums2.length;int left = (m + n + 1) / 2;int right = (m + n + 2) / 2;return (findKth(nums1, 0, nums2, 0, left) + findKth(nums1, 0, nums2, 0, right)) / 2.0;}private int findKth(int[] nums1, int i, int[] nums2, int j, int k) {if (i >= nums1.length) return nums2[j + k - 1];if (j >= nums2.length) return nums1[i + k - 1];if (k == 1) return Math.min(nums1[i], nums2[j]);int midVal1 = (i + k / 2 - 1 < nums1.length) ? nums1[i + k / 2 - 1] : Integer.MAX_VALUE;int midVal2 = (j + k / 2 - 1 < nums2.length) ? nums2[j + k / 2 - 1] : Integer.MAX_VALUE;if (midVal1 < midVal2) {return findKth(nums1, i + k / 2, nums2, j, k - k / 2);} else {return findKth(nums1, i, nums2, j + k / 2, k - k / 2);}}

数组

  • 移动零(LeetCode 283)
    public void moveZeroes(int[] nums) {int j = 0;for (int i = 0; i < nums.length; i++) {if (nums[i] != 0) {nums[j] = nums[i];++j;}}for (int i = j; i < nums.length; i++) {nums[i] = 0;}}
  • 颜色分类(LeetCode 75)
        int left = 0, right = nums.length - 1, current = 0;while (current <= right) {if (nums[current] == 0) {swap(nums, left, current);left++;current++;} else if (nums[current] == 2) {swap(nums, right, current);right--;} else {current++;}}}private void swap(int[] nums, int i, int j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}
  • 旋转有序数组中的搜索(LeetCode 33)
    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;}
  • 合并两个有序数组(LeetCode 88)
    public void merge(int[] nums1, int m, int[] nums2, int n) {int i = m - 1, j = n - 1, k = m + n - 1;while (i >= 0 && j >= 0) {if (nums1[i] > nums2[j]) {nums1[k] = nums1[i];i--;} else {nums1[k] = nums2[j];j--;}k--;}while (j >= 0) {nums1[k] = nums2[j];j--;k--;}}

链表

  • 链表的中间节点(LeetCode 876)
    public ListNode middleNode(ListNode head) {ListNode slow = head, fast = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;}return slow;}
  • 排序链表(LeetCode 148)
    public ListNode sortList(ListNode head) {return sort(head, null);}private ListNode sort(ListNode head, ListNode tail) {if (head == null) return head;if (head.next == tail) {head.next = null;return head;}ListNode slow = head, fast = head;while (fast != tail) {slow = slow.next;fast = fast.next;if (fast != tail) fast = fast.next;}ListNode l1 = sort(head, slow);ListNode l2 = sort(slow, tail);return merge(l1, l2);}private ListNode merge(ListNode n1, ListNode n2) {ListNode dummy = new ListNode();ListNode cur = dummy;while (n1 != null && n2 != null) {if (n1.val <= n2.val) {cur.next = n1;n1 = n1.next;} else {cur.next = n2;n2 = n2.next;}cur = cur.next;}cur.next = n1 != null ? n1 : n2;return dummy.next;}
  • 重排链表(LeetCode 143)
    public void reorderList(ListNode head) {if (head == null) return;// 找到中间转折的点ListNode slow = head;ListNode fast = head;while (fast.next != null && fast.next.next != null) {slow = slow.next;fast = fast.next.next;}System.out.println("slow -> " + slow.val);// 翻转后边的列表ListNode nl = new ListNode();while (slow.next != null) {ListNode tmp = slow.next;// 移除主链表slow.next = slow.next.next;// 放入翻转链表tmp.next = nl.next;nl.next = tmp;}// 合并链表ListNode cur = head;while (nl.next != null) {ListNode tmp = nl.next;nl.next = nl.next.next;// 加入主链表tmp.next = cur.next;cur.next = tmp;cur = cur.next.next;System.out.print(".");}}
  • 反转链表(LeetCode 206)
  public ListNode reverseList(ListNode head) {ListNode prev = null, curr = head;while (curr != null) {ListNode nextTemp = curr.next;curr.next = prev;prev = curr;curr = nextTemp;}   return prev;}
  • 两两交换链表中的节点(LeetCode 24)
    public ListNode swapPairs(ListNode head) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode prev = dummy;while (head != null && head.next != null) {ListNode first = head;ListNode second = head.next;prev.next = second;first.next = second.next;second.next = first;prev = first;head = first.next;}return dummy.next;}
  • 合并 K 个升序链表(LeetCode 23)
    public ListNode mergeKLists(ListNode[] lists) {if (lists == null || lists.length == 0) {return null;}ListNode result = lists[0];for (int i = 1; i < lists.length; i++) {result = mergeTwoLists(result, lists[i]);}return result;}// 合并两个有序链表的方法private ListNode mergeTwoLists(ListNode l1, ListNode l2) {ListNode dummy = new ListNode(0);ListNode current = dummy;while (l1 != null && l2 != null) {if (l1.val < l2.val) {current.next = l1;l1 = l1.next;} else {current.next = l2;l2 = l2.next;}current = current.next;}if (l1 != null) {current.next = l1;}if (l2 != null) {current.next = l2;}return dummy.next;}
  • 环形链表(LeetCode 141)
    public boolean hasCycle(ListNode head) {if (head == null || head.next == null) {return false;}ListNode slow = head;ListNode fast = head.next;while (slow != fast) {if (fast == null || fast.next == null) {return false;}slow = slow.next;fast = fast.next.next;}return true;}
  • 环形链表 II(LeetCode 142)
    public ListNode detectCycle(ListNode head) {Set<ListNode> set = new HashSet<>();ListNode cur = head;while (cur != null) {if (!set.add(cur)) {return cur;}cur = cur.next;}return null;}
  • 删除排序链表中的重复元素(LeetCode 83)
    public ListNode deleteDuplicates(ListNode head) {ListNode cur = head;while (cur != null && cur.next != null) {if (cur.val == cur.next.val) {cur.next = cur.next.next;} else {cur = cur.next;}}return head;}
  • 删除排序链表中的重复元素 II(LeetCode 82)
class Solution {public ListNode deleteDuplicates(ListNode head) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode pre = dummy;ListNode cur = head;while (cur != null) {boolean hasD = false;while (cur.next != null && cur.val == cur.next.val) {hasD = true;cur = cur.next;}if (hasD) {pre.next = cur.next;} else {pre = pre.next;}cur = cur.next;}return dummy.next;}
  • 回文链表(LeetCode 234)
    public boolean isPalindrome(ListNode head) {if (head == null || head.next == null) {return true;}// 找到链表中间节点ListNode slow = head;ListNode fast = head;while (fast.next != null && fast.next.next != null) {slow = slow.next;fast = fast.next.next;}// 反转后半部分链表ListNode secondHalf = reverseList(slow.next);ListNode firstHalf = head;// 比较两部分链表while (secondHalf != null) {if (firstHalf.val != secondHalf.val) {return false;}firstHalf = firstHalf.next;secondHalf = secondHalf.next;}return true;}private ListNode reverseList(ListNode head) {ListNode prev = null;ListNode current = head;while (current != null) {ListNode nextNode = current.next;current.next = prev;prev = current;current = nextNode;}return prev;}
  • 相交链表(LeetCode 160)
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {ListNode pA = headA;ListNode pB = headB;while (pA != pB) {pA = pA != null ? pA.next : headB;pB = pB != null ? pB.next : headA;}return pA;}
  • 奇偶链表(LeetCode 328)
    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;}
  • 删除链表元素(LeetCode 203)
    public ListNode removeElements(ListNode head, int val) {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;}
  • 单链表的倒数第 K 个节点(LeetCode 19)
    public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode first = dummy;ListNode second = dummy;// 让 first 指针先移动 n + 1 步for (int i = 0; i <= n; i++) {first = first.next;}// 同时移动 first 和 second 指针while (first != null) {first = first.next;second = second.next;}// 删除倒数第 n 个节点second.next = second.next.next;return dummy.next;}

  • 有效的括号(LeetCode 20)
    public boolean isValid(String s) {Stack<Character> stack = new Stack<>();for (char c: s.toCharArray()) {if (c == '(' || c == '[' || c == '{') {stack.push(c);} else if (c == ')' && !stack.isEmpty() && stack.peek() == '(') {stack.pop();} else if (c == ']' && !stack.isEmpty() && stack.peek() == '[') {stack.pop();} else if (c == '}' && !stack.isEmpty() && stack.peek() == '{') {stack.pop();} else {return false;}}return stack.isEmpty();}
  • 最小栈(LeetCode 155)
    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 result = 0;while (left < right) {if (height[left] < height[right]) {if (height[left] >= leftMax) {leftMax = height[left];} else {result += leftMax - height[left];}left++;} else {if (height[right] >= rightMax) {rightMax = height[right];} else {result += rightMax - height[right];}right--;}}return result;}
  • 接雨水(LeetCode 42)
    public int largestRectangleArea(int[] heights) {if (heights == null || heights.length == 0) {return 0;}int n = heights.length;int[] left = new int[n];int[] right = new int[n];Stack<Integer> stack = new Stack<>();for (int i = 0; i < n; i++) {while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {stack.pop();}left[i] = stack.isEmpty() ? -1 : stack.peek();stack.push(i);}stack.clear();for (int i = n - 1; i >= 0; i--) {while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {stack.pop();}right[i] = stack.isEmpty() ? n : stack.peek();stack.push(i);}int maxArea = 0;for (int i = 0; i < n; i++) {maxArea = Math.max(maxArea, heights[i] * (right[i] - left[i] - 1));}return maxArea;}
  • 直方图中的最大矩形(LeetCode 84)
    public int largestRectangleArea(int[] heights) {if (heights == null || heights.length == 0) {return 0;}int n = heights.length;int[] left = new int[n];int[] right = new int[n];Stack<Integer> stack = new Stack<>();for (int i = 0; i < n; i++) {while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {stack.pop();}left[i] = stack.isEmpty() ? -1 : stack.peek();stack.push(i);}stack.clear();for (int i = n - 1; i >= 0; i--) {while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {stack.pop();}right[i] = stack.isEmpty() ? n : stack.peek();stack.push(i);}int maxArea = 0;for (int i = 0; i < n; i++) {maxArea = Math.max(maxArea, heights[i] * (right[i] - left[i] - 1));}return maxArea;}

队列

  • 滑动窗口最大值(LeetCode 239)
    public int[] maxSlidingWindow(int[] nums, int k) {if (nums == null || nums.length == 0) {return new int[0];}int n = nums.length;int[] result = new int[n - k + 1];Deque<Integer> deque = new ArrayDeque<>();for (int i = 0; i < n; 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;}
  • 最小窗口子串(LeetCode 76)
    public String minWindow(String s, String t) {if (s == null || s.length() == 0 || t == null || t.length() == 0) {return "";}int[] need = new int[128];for (char c : t.toCharArray()) {need[c]++;}int left = 0, right = 0, start = 0, minLen = Integer.MAX_VALUE, count = t.length();while (right < s.length()) {char c = s.charAt(right);if (need[c] > 0) {count--;}need[c]--;right++;while (count == 0) {if (right - left < minLen) {minLen = right - left;start = left;}char leftChar = s.charAt(left);need[leftChar]++;if (need[leftChar] > 0) {count++;}left++;}}return minLen == Integer.MAX_VALUE ? "" : s.substring(start, start + minLen);}
  • 设计循环双端队列(LeetCode 641)
    private int[] data;private int front;private int rear;private int size;public MyCircularDeque(int k) {data = new int[k];front = 0;rear = 0;size = 0;}public boolean insertFront(int value) {if (isFull()) {return false;}front = (front - 1 + data.length) % data.length;data[front] = value;size++;return true;}public boolean insertLast(int value) {if (isFull()) {return false;}data[rear] = value;rear = (rear + 1) % data.length;size++;return true;}public boolean deleteFront() {if (isEmpty()) {return false;}front = (front + 1) % data.length;size--;return true;}public boolean deleteLast() {if (isEmpty()) {return false;}rear = (rear - 1 + data.length) % data.length;size--;return true;}public int getFront() {if (isEmpty()) {return -1;}return data[front];}public int getRear() {if (isEmpty()) {return -1;}return data[(rear - 1 + data.length) % data.length];}public boolean isEmpty() {return size == 0;}public boolean isFull() {return size == data.length;}

双指针

  • 两数之和(LeetCode 167)
    public int[] twoSum(int[] numbers, int target) {int left = 0;int right = numbers.length - 1;while (left < right) {int sum = numbers[left] + numbers[right];if (sum == target) {return new int[]{left + 1, right + 1};} else if (sum < target) {left++;} else {right--;}}// This line should never be reached since there is exactly one solutionreturn new int[]{-1, -1};}
}
  • 三数之和(LeetCode 15)
    public List<List<Integer>> threeSum(int[] nums) {// Initialize the result list to store the tripletsList<List<Integer>> result = new ArrayList<>();// Sort the array in ascending order to simplify the process of finding tripletsArrays.sort(nums);// Iterate through the array, considering each element as a potential first element of a tripletfor (int i = 0; i < nums.length - 2; i++) {// Skip duplicates for the first number to avoid duplicate tripletsif (i > 0 && nums[i] == nums[i - 1]) continue;// Initialize two pointers, one at the next element and one at the end of the arrayint left = i + 1;int right = nums.length - 1;// Calculate the target sum for the other two numbersint target = -nums[i];// Use two-pointer approach to find the other two numbers that sum up to the targetwhile (left < right) {// Calculate the sum of the two numbers pointed by the left and right pointersint sum = nums[left] + nums[right];// If the sum is equal to the target, we found a tripletif (sum == target) {// Add the triplet to the result listresult.add(Arrays.asList(nums[i], nums[left], nums[right]));// Skip duplicates for the second and third numberswhile (left < right && nums[left] == nums[left + 1]) left++;while (left < right && nums[right] == nums[right - 1]) right--;// Move the pointers to the next unique numbersleft++;right--;}// If the sum is less than the target, move the left pointer to the right to increase the sumelse if (sum < target) {left++;}// If the sum is greater than the target, move the right pointer to the left to decrease the sumelse {right--;}}}// Return the list of tripletsreturn result;}
  • 四数之和(LeetCode 18)
    public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> result = new ArrayList<>();Arrays.sort(nums); // Sort the array firstfor (int i = 0; i < nums.length - 3; i++) {// Skip duplicates for the first numberif (i > 0 && nums[i] == nums[i - 1]) continue;for (int j = i + 1; j < nums.length - 2; j++) {// Skip duplicates for the second numberif (j > i + 1 && nums[j] == nums[j - 1]) continue;int left = j + 1;int right = nums.length - 1;long newTarget = (long) target - nums[i] - nums[j];while (left < right) {long sum = (long) nums[left] + nums[right];if (sum == newTarget) {result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));// Skip duplicates for the third and fourth numberswhile (left < right && nums[left] == nums[left + 1]) left++;while (left < right && nums[right] == nums[right - 1]) right--;left++;right--;} else if (sum < newTarget) {left++;} else {right--;}}}}return result;}
  • 移除元素(LeetCode 27)
    public int removeElement(int[] nums, int val) {int k = 0; // Initialize the pointer for the next position to place a non-val elementfor (int i = 0; i < nums.length; i++) {if (nums[i] != val) {nums[k] = nums[i]; // Place the non-val element at the next positionk++; // Move the pointer to the next position}}return k; // Return the number of elements that are not equal to val}
  • 反转字符串(LeetCode 344)
    public boolean isPalindrome(String s) {// Convert the string to lowercase and remove non-alphanumeric charactersString cleanString = s.toLowerCase().replaceAll("[^a-z0-9]", "");// Check if the clean string is a palindromeint left = 0;int right = cleanString.length() - 1;while (left < right) {if (cleanString.charAt(left) != cleanString.charAt(right)) {return false;}left++;right--;}return true;}
  • 验证回文串(LeetCode 125)
    public boolean isPalindrome(String s) {String cleanStr = s.toLowerCase().replaceAll("[^a-z0-9]", "");int left = 0;int right = cleanStr.length() - 1;while(left < right) {if(cleanStr.charAt(left) != cleanStr.charAt(right)) {return false;}left++;right--;}return true;}

哈希表

  • 两数之和(LeetCode 1)
    public int[] twoSum(int[] nums, int target) {if (nums == null || nums.length == 0) {return new int[0];}Map<Integer, Integer> map = new HashMap<>();for (int i = 0; i < nums.length; i++) {int com = target - nums[i];if (map.containsKey(com)) {return new int[]{map.get(com), i};}map.put(nums[i], i);}return new int[0];}
  • 字母异位词分组(LeetCode 49)
    public List<List<String>> groupAnagrams(String[] strs) {if (strs == null || strs.length == 0) {return new ArrayList<>();}Map<String, List<String>> map = new HashMap<>();for (String str : strs) {char[] charArray = str.toCharArray();Arrays.sort(charArray);String sortedStr = new String(charArray);if (!map.containsKey(sortedStr)) {map.put(sortedStr, new ArrayList<>());}map.get(sortedStr).add(str);}return new ArrayList<>(map.values());}
  • 四数相加 II(LeetCode 454)
    public List<List<String>> groupAnagrams(String[] strs) {if (strs == null || strs.length == 0) {return new ArrayList<>();}Map<String, List<String>> map = new HashMap<>();for (String str : strs) {char[] charArray = str.toCharArray();Arrays.sort(charArray);String sortedStr = new String(charArray);if (!map.containsKey(sortedStr)) {map.put(sortedStr, new ArrayList<>());}map.get(sortedStr).add(str);}return new ArrayList<>(map.values());}
  • 快乐数(LeetCode 202)
    public boolean isHappy(int n) {Set<Integer> set = new HashSet<>();while (n != 1 && !set.contains(n)) {set.add(n);n = getNext(n);}return n == 1;}private int getNext(int n) {int total = 0;while(n > 0) {int digit = n % 10;total += digit * digit;n = n / 10;}return total;}
  • 赎金信(LeetCode 383)
    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;}
  • 第一个只出现一次的字符(LeetCode 387)
    public int firstUniqChar(String s) {Map<Character, Integer> map = new HashMap<>();char[] charArray = s.toCharArray();for (char c : charArray) {map.put(c, map.getOrDefault(c, 0) + 1);}for (int i = 0; i < charArray.length; i++) {if (map.get(charArray[i]) == 1) {return i;}}return -1;}
  • 存在重复元素(LeetCode 217)
    public boolean containsDuplicate(int[] nums) {Set<Integer> set = new HashSet<>();for (int num : nums) {if (!set.add(num)) {return true;}}return false;}
  • 存在重复元素 II(LeetCode 219)
    public boolean containsNearbyDuplicate(int[] nums, int k) {Map<Integer, Integer> map = new HashMap<>();for (int i = 0; i < nums.length; i++) {int num = nums[i];if (map.containsKey(num) && i - map.get(num) <= k) {return true;}map.put(num, i);}return false;}
  • 两个数组的交集(LeetCode 349)
    public int[] intersection(int[] nums1, int[] nums2) {Set<Integer> set1 = new HashSet<>();for (int num : nums1) {set1.add(num);}Set<Integer> set2 = new HashSet<>();for (int num : nums2) {if (set1.contains(num)) {set2.add(num;)}}int[] result = new int[set2.size()];int index = 0;for (int num : set2) {result[i++] = num;}return result;}
  • 两个数组的交集 II(LeetCode 350)
    public int[] intersection(int[] nums1, int[] nums2) {Set<Integer> set1 = new HashSet<>();for (int num : nums1) {set1.add(num);}Set<Integer> set2 = new HashSet<>();for (int num : nums2) {if (set1.contains(num)) {set2.add(num);}}int[] result = new int[set2.size()];int index = 0;for (int num : set2) {result[index++] = num;}return result;}

前缀和

  • 最大子序和(LeetCode 53)
    public int maxSubArray(int[] nums) {if (nums == null || nums.length == 0) {return 0;}int n = nums.length;int[] prefixSum = new int[n + 1];prefixSum[0] = 0;for (int i = 1; i <= n; i++) {prefixSum[i] = prefixSum[i - 1] + nums[i - 1];}int minPrefixSum = 0;int maxSubArraySum = Integer.MIN_VALUE;for (int i = 1; i <= n; i++) {maxSubArraySum = Math.max(maxSubArraySum, prefixSum[i] - minPrefixSum);minPrefixSum = Math.min(minPrefixSum, prefixSum[i]);}return maxSubArraySum;}
  • 和为 K 的子数组(LeetCode 560)
    public int subarraySum(int[] nums, int k) {if (nums == null || nums.length == 0) {return 0;}int count = 0;int prefixNum = 0;Map<Integer, Integer> map = new HashMap<>();map.put(0, 1);for (int num: nums) {prefixNum += num;if (map.containsKey(prefixNum - k)) {count += map.get(prefixNum - k);}map.put(prefixNum, map.getOrDefault(prefixNum, 0) + 1);}return count;}
  • 寻找数组的中心下标(LeetCode 724)
    public int pivotIndex(int[] nums) {if (nums == null || nums.length == 0) {return -1;}int total = 0;for (int num: nums) {total += num;}int left = 0;for (int i = 0; i < nums.length; i++) {if (left == total - left - nums[i]) {return i;}left += nums[i];}return -1;}
  • 长度最小的子数组(LeetCode 209)
    public int minSubArrayLen(int target, int[] nums) {if (nums == null || nums.length == 0) {return 0;}int min = Integer.MAX_VALUE;int left = 0;int sum = 0;for (int right = 0; right < nums.length; right++) {sum += nums[right];while (sum >= target) {min = Math.min(min, right - left + 1);sum -= nums[left];left++;}}return min == Integer.MAX_VALUE ? 0 : min;}

二叉树

  • 二叉树的前序遍历(LeetCode 144)
    public List<Integer> preorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();preorder(root, result);return result;}private void preorder(TreeNode node, List<Integer> result) {if (node == null) {return;}result.add(node.val);preorder(node.left, result);preorder(node.right, result);}
  • 二叉树的中序遍历(LeetCode 94)
    public List<Integer> inorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();inorder(root, result);return result;}private void inorder(TreeNode node, List<Integer> result) {if (node == null) {return;}inorder(node.left, result);result.add(node.val);inorder(node.right, result);}
  • 二叉树的后序遍历(LeetCode 145)
    public List<Integer> inorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();inorder(root, result);return result;}private void inorder(TreeNode node, List<Integer> result) {if (node == null) {return;}inorder(node.left, result);inorder(node.right, result);result.add(node.val);}
  • 最大二叉树(LeetCode 654)
    public TreeNode constructMaximumBinaryTree(int[] nums) {return build(nums, 0, nums.length - 1);}private TreeNode build(int[] nums, int left, int right) {if (left > right) {return null;}int maxIndex = left;for (int i = left + 1; i <= right; i++) {if (nums[i] > nums[maxIndex]) {maxIndex = i;}}TreeNode root = new TreeNode(nums[maxIndex]);root.left = build(nums, left, maxIndex - 1);root.right = build(nums, maxIndex + 1, right);return root;}
  • 二叉树的层序遍历(LeetCode 102)
    public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> result = new ArrayList<>();if (root == null) {return result;}LinkedList<TreeNode> queue = new LinkedList<>();queue.add(root);while (!queue.isEmpty()) {int levelSize = queue.size();List<Integer> currentLevel = new ArrayList<>();for (int i = 0; i < levelSize; i++) {TreeNode node = queue.pollFirst();currentLevel.add(node.val);if (node.left != null) {queue.offerLast(node.left);}if (node.right != null) {queue.offerLast(node.right);}}result.add(currentLevel);}return result;}
  • 二叉树的最小深度(LeetCode 111)
    public int minDepth(TreeNode root) {if (root == null) {return 0;}if (root.left == null && root.right == null) {return 1;}int minDepth = Integer.MAX_VALUE;if (root.left != null) {minDepth = Math.min(minDepth, minDepth(root.left));}if (root.right != null) {minDepth = Math.min(minDepth, minDepth(root.right));}return minDepth + 1;}
  • 二叉树的最大深度(LeetCode 104)
    public int maxDepth(TreeNode root) {if (root == null) {return 0;}   int leftDepth = maxDepth(root.left);int rightDepth = maxDepth(root.right);return Math.max(leftDepth, rightDepth) + 1;}
  • 二叉树的最近公共祖先(LeetCode 236)
    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;} else if (left != null) {return left;} else {return right;}}
  • 对称二叉树(LeetCode 101)
    public boolean isSymmetric(TreeNode root) {if (root == null) {return true;}return isMirror(root.left, root.right);}private boolean isMirror(TreeNode left, TreeNode right) {if (left == null && right == null) {return true;}if (left == null || right == null) {return false;}return (left.val == right.val) && isMirror(left.left, right.right) && isMirror(left.left, right.left);}
  • 翻转二叉树(LeetCode 226)
    public TreeNode invertTree(TreeNode root) {if (root == null) {return null;}TreeNode temp = root.left;root.left = root.right;root.right = temp;invertTree(root.left);invertTree(root.right);return root;}
  • 从中序与后序遍历序列构造二叉树
    public TreeNode buildTree(int[] inorder, int[] postorder) {return build(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);}private TreeNode build(int[] inorder, int inStart, int inEnd, int[] postorder, int postStart, int postEnd) {if (inStart > inEnd || postStart > postEnd) {return null;}int rootVal = postorder[postEnd];TreeNode root = new TreeNode(rootVal);int rootIndexInorder = 0;for (int i = inStart; i <= inEnd; i++) {if (inorder[i] == rootVal) {rootIndexInorder = i;break;}}int leftSubtreeSize = rootIndexInorder - inStart;root.left = build(inorder, inStart, rootIndexInorder - 1, postorder, postStart, postStart + leftSubtreeSize - 1);root.right = build(inorder, rootIndexInorder + 1, inEnd, postorder, postStart + leftSubtreeSize, postEnd - 1);return root;}
  • 从前序与中序遍历序列构造二叉树(LeetCode 105)
    public TreeNode buildTree(int[] preorder, int[] inorder) {return build(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);}private TreeNode build(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd) {if (preStart > preEnd || inStart > inEnd) {return null;}int rootVal = preorder[preStart];TreeNode root = new TreeNode(rootVal);int rootIndexInorder = 0;for (int i = inStart; i <= inEnd; i++) {if (inorder[i] == rootVal) {rootIndexInorder = i;break;}}int leftSubtreeSize = rootIndexInorder - inStart;root.left = build(preorder, preStart + 1, preStart + leftSubtreeSize, inorder, inStart, rootIndexInorder - 1);root.right = build(preorder, preStart + leftSubtreeSize + 1, preEnd, inorder, rootIndexInorder + 1, inEnd);return root;}

http://www.ppmy.cn/devtools/160112.html

相关文章

I2C、SPI、UART

I2C&#xff1a;串口通信&#xff0c;同步&#xff0c;半双工&#xff0c;双线&#xff08;数据线SDA时钟线SCL&#xff09;&#xff0c;最大距离1米到几米 SPI&#xff08;串行外设接口&#xff09;&#xff1a;串口通信&#xff0c;同步&#xff0c;全双工&#xff0c;四线&…

bash脚本----传参的处理

Linux脚本&#xff1a;Bash脚本看这一篇就够了-CSDN博客 脚本传参&#xff1a; ./my_script.sh arg1 arg2 arg3 使用以下几个变量进行处理&#xff1a; $0 #即命令本身(my_script.sh)&#xff0c;相当于c/c中的argv[0]&#xff1b; $1 #第一个参数(arg1)&#xff0c;…

第一章——1.2 Java“白皮书”的关键术语

《Java 核心技术卷I》第一章的1.2节介绍了Java“白皮书”中的关键术语&#xff0c;这些术语是Java设计初衷和核心特性的总结。以下是这些关键术语的详细解释和总结&#xff1a; 1.2 Java“白皮书”的关键术语 简单性&#xff08;Simple&#xff09;&#xff1a; Java设计目标是…

openGauss 3.0 数据库在线实训课程19:学习用户和角色管理

前提 我正在参加21天养成好习惯| 第二届openGauss每日一练活动 课程详见&#xff1a;openGauss 3.0.0数据库在线实训课程 学习目标 掌握openGauss的用户和角色管理。 课程作业 1、创建test10_tbs的表空间&#xff0c;在这个表空间中创建数据库testdb10 使用create user创…

人工智能对抗生成网络之基于CycleGan图像合成源码解读

先外网下载与安装visdom,配置好visdom可视化工具,然后训练时才不报错。 (1)CycleGan网络所需数据 CycleGan例如可以把马变成斑马,把某个名星图像变成另外一个人的图像。 CycleGan只需二个数据集,不需一一对应关系,不需配对的数据集&#xff0c;让网络自己去学习与配对。例如…

Effective Objective-C 2.0 读书笔记——大中枢派发

Effective Objective-C 2.0 读书笔记——大中枢派发 多用派发队列&#xff0c;少用同步锁 说到同步锁&#xff0c;我们不难想起我们前面在学习线程之中的内容时学习到的关键字synchronized&#xff0c;使用这个同步块可以让我们这段程序实现加锁的操作&#xff0c;即在不同线…

MySQL数据库(3)—— 表操作

目录 一&#xff0c;创建表 1.1 创建表的SQL 1.2 演示 二&#xff0c;查看表 三&#xff0c;修改表 四&#xff0c;删除表 常用的表操作会涉及到两种SWL语句 DDL&#xff08;Data Definition Language&#xff09;数据定义语言&#xff1a;建表、改表、删表等&#xff0…

机器学习_14 随机森林知识点总结

随机森林&#xff08;Random Forest&#xff09;是一种强大的集成学习算法&#xff0c;广泛应用于分类和回归任务。它通过构建多棵决策树并综合它们的预测结果&#xff0c;显著提高了模型的稳定性和准确性。今天&#xff0c;我们就来深入探讨随机森林的原理、实现和应用。 一、…