# algo-leetcode-100 **Repository Path**: lb_xx/algo-leetcode-100 ## Basic Information - **Project Name**: algo-leetcode-100 - **Description**: 这是一个专门用于练习 LeetCode 热题 100 的 Java 项目。项目采用 Maven 构建,包含完整的测试框架,方便进行算法题的练习和验证。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-05-28 - **Last Updated**: 2025-07-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # LeetCode 100 算法练习 ## 📖 项目介绍 这是一个专门用于练习 LeetCode 热题 100 的 Java 项目。项目采用 Maven 构建,包含完整的测试框架,方便进行算法题的练习和验证。 ## 🏗️ 项目结构 ``` algo-leetcode-100/ ├── src/ │ ├── main/ │ │ └── java/ │ │ └── org/ │ │ └── xiaoxin/ │ │ └── leetcode/ │ │ ├── array/ # 数组相关题目 │ │ ├── string/ # 字符串相关题目 │ │ ├── linkedlist/ # 链表相关题目 │ │ ├── tree/ # 树相关题目 │ │ ├── dp/ # 动态规划题目 │ │ ├── greedy/ # 贪心算法题目 │ │ ├── backtrack/ # 回溯算法题目 │ │ ├── graph/ # 图相关题目 │ │ └── utils/ # 工具类 │ └── test/ │ └── java/ │ └── org/ │ └── xiaoxin/ │ └── leetcode/ # 对应的测试类 ├── docs/ │ ├── solutions/ # 题解文档 │ └── notes/ # 学习笔记 ├── pom.xml └── README.md ``` ## 🚀 快速开始 ### 环境要求 - Java 8 - Maven 3.6+ - IDE (推荐 IntelliJ IDEA) ### 运行项目 ```bash # 克隆项目 git clone https://gitee.com/lb_xx/algo-leetcode-100.git cd algo-leetcode-100 # 编译项目 mvn compile # 运行测试 mvn test # 运行特定题目 mvn exec:java -Dexec.mainClass="org.xiaoxin.leetcode.array.TwoSum" ``` ## 📝 编码规范 ### 文件命名规范 - 类名格式:`_题目编号_题目名称.java` - 例如:`_001_TwoSum.java`、`_002_AddTwoNumbers.java` ### 代码模板 ```java package org.xiaoxin.leetcode.array; import java.util.Arrays; /** * 1. 两数之和 *
* 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值 target 的那两个整数,并返回它们的数组下标。 *
* 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 *
* 你可以按任意顺序返回答案。 *
* 示例 1: * 输入:nums = [2,7,11,15], target = 9 * 输出:[0,1] * 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。 *
* 难度:简单 * 标签:数组、哈希表 * * @author xiaoxin */ public class _001_TwoSum { /** * 方法一:暴力解法 * 思路:双重循环遍历所有可能的两数组合 * 时间复杂度:O(n²) * 空间复杂度:O(1) */ public int[] twoSum(int[] nums, int target) { // TODO: 实现暴力算法 return new int[0]; } /** * 方法二:哈希表(推荐) * 思路:使用哈希表存储已遍历的数字和对应的索引 * 时间复杂度:O(n) * 空间复杂度:O(n) */ public int[] twoSum2(int[] nums, int target) { // TODO: 实现哈希表算法 return new int[0]; } public static void main(String[] args) { testAllMethods(); } /** * 测试所有方法 */ private static void testAllMethods() { System.out.println("=== 1. 两数之和 - 测试用例 ===\n"); _001_TwoSum solution = new _001_TwoSum(); // 示例测试 int[] nums = {2, 7, 11, 15}; int target = 9; System.out.println("输入数组: " + Arrays.toString(nums)); System.out.println("目标值: " + target); System.out.println("方法一结果: " + Arrays.toString(solution.twoSum(nums, target))); System.out.println("方法二结果: " + Arrays.toString(solution.twoSum2(nums, target))); } } ``` ## 📚 学习计划 ### 第一阶段:基础数据结构 (1-30题) - [ ] 数组 (Array) - [ ] 字符串 (String) - [ ] 链表 (LinkedList) - [ ] 栈和队列 (Stack & Queue) ### 第二阶段:树和图 (31-60题) - [ ] 二叉树 (Binary Tree) - [ ] 二叉搜索树 (BST) - [ ] 图的遍历 (Graph Traversal) ### 第三阶段:算法思想 (61-100题) - [ ] 动态规划 (Dynamic Programming) - [ ] 贪心算法 (Greedy) - [ ] 回溯算法 (Backtracking) - [ ] 分治算法 (Divide and Conquer) ## 🎯 刷题技巧 1. **理解题意**:仔细阅读题目,理解输入输出要求 2. **分析复杂度**:思考时间和空间复杂度 3. **多种解法**:尝试不同的解决方案 4. **总结归纳**:记录解题思路和易错点 ## 📊 进度追踪 **总进度: 9/100** 🎯 ### 已完成题目 ✅ | 题号 | 题目名称 | 难度 | 标签 | 完成日期 | |-----|--------------|----|--------------------|------------| | 1 | 两数之和 | 简单 | 数组、哈希表 | 2025-05-28 | | 3 | 无重复字符的最长子串 | 中等 | 哈希表、字符串、滑动窗口 | 2025-06-13 | | 11 | 盛最多水的容器 | 中等 | 数组、双指针、贪心 | 2025-06-03 | | 15 | 三数之和 | 中等 | 数组、双指针、排序 | 2025-06-11 | | 49 | 字母异位词分组 | 中等 | 数组、哈希表、字符串、排序 | 2025-05-30 | | 128 | 最长连续序列 | 中等 | 并查集、数组、哈希表 | 2025-05-30 | | 283 | 移动零 | 简单 | 数组、双指针 | 2025-05-30 | | 438 | 找到字符串中所有字母异位词 | 中等 | 哈希表、字符串、滑动窗口 | 2025-06-15 | | 560 | 和为K的子数组 | 中等 | 数组、哈希表、前缀和 | 2025-07-09 | ### 按分类统计 | 分类 | 已完成 | 总计 | 进度 | |------|-----|-----|-----| | 数组 | 7 | ~15 | 47% | | 字符串 | 2 | ~10 | 20% | | 链表 | 0 | ~8 | 0% | | 树 | 0 | ~15 | 0% | | 动态规划 | 0 | ~20 | 0% | | 其他 | 0 | ~32 | 0% | ### 算法技巧掌握情况 - ✅ **双指针**: 盛最多水的容器、三数之和、移动零 - ✅ **哈希表**: 两数之和、字母异位词分组、最长连续序列 - ✅ **排序**: 三数之和、字母异位词分组 - ✅ **滑动窗口**: 无重复字符的最长子串、找到字符串中所有字母异位词 - ✅ **前缀和**: 和为K的子数组 - ⏳ **动态规划**: 待学习 - ⏳ **回溯算法**: 待学习 ## 🔗 相关资源 - [Hello 算法](https://www.hello-algo.com/chapter_hello_algo/) - [LeetCode 官网](https://leetcode.cn/) - [LeetCode 热题 100](https://leetcode.cn/studyplan/top-100-liked/) ## 💡 算法技巧总结 ### 双指针技巧 #### 相向双指针 - **适用场景**: 有序数组中查找满足条件的两个元素、求和问题 - **核心思想**: 从数组两端向中间移动,根据条件调整指针位置 - **经典题目**: - 盛最多水的容器(#11): 左右指针分别指向容器的两个边界,计算当前面积并移动较短的边 - 三数之和(#15): 固定一个数,然后用双指针在剩余数组中寻找两个数使三数之和为0 - **优化技巧**: - 排序预处理可以简化双指针的移动逻辑 - 跳过重复元素避免重复计算 #### 快慢双指针 - **适用场景**: 原地修改数组、链表操作、检测环 - **核心思想**: 两个指针以不同速度在数组/链表上移动 - **经典题目**: - 移动零(#283): 快指针寻找非零元素,慢指针指向待填充位置 - **优化技巧**: - 使用交换操作减少元素移动次数 - 注意边界条件和指针初始位置 ### 哈希表技巧 - **查找优化**: - 两数之和(#1): 将O(n²)的查找优化为O(n),存储已遍历元素及其索引 - 无重复字符的最长子串(#3): 记录字符最后出现的位置,优化滑动窗口的左边界移动 - **分组计数**: - 字母异位词分组(#49): 使用排序后的字符串作为键,将异位词分到同一组 - 最长连续序列(#128): 使用哈希表存储所有元素,快速查找连续序列 - **实现技巧**: - 选择合适的键值对设计(如排序字符串、字符频率数组等) - 考虑使用数组替代哈希表提高效率(如ASCII字符集) ### 排序技巧 - **预处理**: - 三数之和(#15): 排序后使用双指针,简化去重和查找逻辑 - 字母异位词分组(#49): 对每个字符串排序作为哈希表的键 - **排序算法选择**: - 小数据量或需要稳定排序: 插入排序、归并排序 - 大数据量且不要求稳定: 快速排序、堆排序 - 特殊数据范围: 计数排序、基数排序 - **优化方向**: - 利用数据特性选择合适的排序算法 - 部分排序而非完全排序(如快速选择算法) ### 滑动窗口技巧 - **窗口定义与维护**: - 使用左右指针定义窗口边界 - 右指针扩展窗口,左指针收缩窗口 - 维护窗口内的状态(如无重复字符、元素和等) - **经典题目**: - 无重复字符的最长子串(#3): 维护一个无重复字符的窗口,遇到重复字符时收缩左边界 - 找到字符串中所有字母异位词(#438): 维护固定大小的滑动窗口,比较窗口内字符频率与模式串字符频率 - **实现模式**: ```java // 基本模式 int left = 0, right = 0; while (right < s.length()) { // 扩大窗口 window.add(s.charAt(right)); right++; // 根据条件收缩窗口 while (需要收缩的条件) { window.remove(s.charAt(left)); left++; } // 更新结果 } ``` - **优化技巧**: - 使用哈希表记录窗口内元素,实现O(1)查找 - 对于字符串问题,可以使用数组替代哈希表提高效率 - 直接跳跃优化: 记录元素位置,发现重复时直接跳到重复元素之后 ### 前缀和技巧 - **基本概念**: - 前缀和是指数组中前i个元素的累加和 - 可以快速计算任意区间[i,j]的和: sum(i,j) = prefixSum[j] - prefixSum[i-1] - **经典题目**: - 和为K的子数组(#560): 使用哈希表记录前缀和出现的次数,快速查找满足条件的子数组 - **实现模式**: ```java // 基本模式 int[] prefixSum = new int[n + 1]; // prefixSum[0] = 0 for (int i = 1; i <= n; i++) { prefixSum[i] = prefixSum[i - 1] + nums[i - 1]; } // 计算区间[i,j]的和 int rangeSum = prefixSum[j + 1] - prefixSum[i]; ``` - **优化技巧**: - 结合哈希表优化查找操作,将时间复杂度从O(n²)降低到O(n) - 使用滚动变量代替前缀和数组,减少空间使用 - 注意处理前缀和为0的情况,通常需要在哈希表中初始化{0, 1} ## 📝 更新日志 - **2025-07-09**: 新增 560.和为K的子数组(前缀和 + 哈希表) - **2025-06-15**: 新增 438.找到字符串中所有字母异位词(滑动窗口 + 哈希表) - **2025-06-13**: 新增 3.无重复字符的最长子串(滑动窗口 + 哈希表) - **2025-06-11**: 新增 15.三数之和(双指针 + 排序,完善去重逻辑) - **2025-06-03**: 11.盛最多水的容器(双指针贪心算法) - **2025-05-30**: 49.字母异位词分组、128.最长连续序列、283.移动零 - **2025-05-28**: 项目初始化(希望能坚持到100题!),完成 1.两数之和 --- **Happy Coding! 🚀**