人的天性:避难趋易,急于求成
数组
- 二分法
- 双指针
- 快慢指针:快指针判断,慢指针更新
- 左右指针
- 滑动窗口
链表
- 种类:单链表,双链表,循环链表
- 例题
- 203 移除链表元素
- 虚拟头节点
- 707 设计链表
- 206 反转链表
- 24 两两交换链表中的节点
- 19 删除链表的倒数第N个节点
- 160 相交链表
- 142 环形链表II
- 判断是否有环:快慢指针
- 判断是否有环:快慢指针
- 203 移除链表元素
哈希表
- 场景
- 查找时间复杂度: O ( 1 ) O(1) O(1)
- 查找元素是否在数组、字符串中
- 例题
字符串
双指针
栈与队列
- 例题
- 232 用栈实现队列
- 注意pop和peek操作
- 注意pop和peek操作
- 225 用队列实现栈
- 注意push操作
- 注意push操作
- 20 有效的括号
- 1047 删除字符串中的所有相邻重复项
- 150 逆波兰表达式求值
- 239 滑动窗口最大值
- 单调队列的实现 (offer, poll)
- 单调队列的实现 (offer, poll)
- 349 前k个高频元素
- 优先队列的实现 (Comparator)
- 232 用栈实现队列
二叉树
- 递归版本和迭代版本
- 例题
- 二叉树的遍历
- 二叉树的属性
- 二叉树的修改与构造
- 二叉搜索树的属性
- 二叉搜索树的修改与构造
- 公共祖先
回溯
- 例题
贪心
- 性质
- 最优子结构
- 贪心选择性质
- 例题
动态规划
- 性质
- 最优子结构
- 子问题重叠
- 例题
- 基础题目
- 背包问题
- 46 携带研究材料(01背包)
- 01背包
- 滚动数组
- 416 分割等和子集
- 1049 最后一块石头的重量II
- 494 目标和
- 474 一和零
- 52 携带研究材料(完全背包)
- 完全背包
- 滚动数组
- 518 零钱兑换II
- 求组合数,外层遍历数组,内层遍历背包
- 377 组合总和IV
- 求排列数,外层遍历背包,内层遍历数组
- 57 爬楼梯
- 322 零钱兑换
- 279 完全平方数
- 56 携带矿石资源(多重背包)
- 46 携带研究材料(01背包)
- 打家劫舍
- 股票问题
- 子序列问题
图论
数据库
- 查询
- 连接
- join, left join, right join, on
- 1378 使用唯一标识码替换员工ID
- 聚合函数
- avg, sum, count, max, min, round, ceil, floor
- 620 有趣的电影
- 分组和排序
- group by, having, order by, asc/desc
- 2356 每位教师所教授的科目种类的数量
- 高级查询和连接
- 子查询
预备知识
输入输出
- 输入:Scanner: next, nextLine, nextByte, nextShort(), nextInt, nextLong, nextFloat, nextDouble
Scanner scan = new Scanner(System.in); while(scan.hasNextXxx()){ scan.nextXxx(); }
- 输出
System.out.print(); System.out.println(); System.out.printf("%b %d %x %.2f %.2e %s", true, 10, 10, 1.1f, 2.2, "hello");
数据结构
- 简单数据类型
- char, byte, short, int, long, float, double
- 数据类型转换
- 简单数据类型转换
- 低转高:自动类型提升
- byte/short -> int -> long -> float -> double
- 高转低:强制类型转换(损失精度)
- double -> float -> long -> int -> byte/short
- 低转高:自动类型提升
- 字符串与其他数据类型的相互转换
- 字符串转其他
- Integer.parseInt, Float.parseFloat, Double.parseDouble
- Integer.valueOf, Float.valueOf, Double.valueOf, String.valueOf
- 其他转字符串
- Integer.toString, Float.toString, Double.toString
- 字符串转其他
- 简单数据类型转换
- 数组
- char[], byte[], short[], int[], long[], float[], double[]
- 常用属性:length
- 常用方法:equals, toString, Arrays.binarySearch, Arrays.sort, Arrays.copyOfRange, Arrays.asList
- 字符串
- String
- 常用方法:length, charAt, substring, isEmpty
- StringBuilder
- 常用方法:length, charAt, substring, toString, append, insert, delete, deleteCharAt, reverse
- String
- 链表节点
public class ListNode { int val; ListNode next; ListNode() {} ListNode(int val) { this.val = val; } ListNode(int val, ListNode next) { this.val = val; this.next = next; } }
- 二叉树节点
public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode() {} TreeNode(int val) { this.val = val; } TreeNode(int val, TreeNode left, TreeNode right) { this.val = val; this.left = left; this.right = right; } }
class Utils { public TreeNode buildTree(Object[] arrays) { TreeNode root = new TreeNode(); Queue<TreeNode> nodeQueue = new LinkedList<>(); int idx = 0; if (idx < arrays.length && arrays[idx] != null) { root.val = (int)arrays[idx]; nodeQueue.offer(root); } while (idx < arrays.length && !nodeQueue.isEmpty()) { int count = nodeQueue.size(); while (count > 0) { TreeNode node = nodeQueue.poll(); int leftIdx = 2 * idx + 1; int rightIdx = 2 * idx + 2; if (leftIdx < arrays.length && arrays[leftIdx] != null) { node.left = new TreeNode((int)arrays[leftIdx]); nodeQueue.offer(node.left); } else { node.left = null; } if (rightIdx < arrays.length && arrays[rightIdx] != null) { node.right = new TreeNode((int)arrays[rightIdx]); nodeQueue.offer(node.right); } else { node.right = null; } idx++; count--; } } return root; } }
Java集合
- Collection 接口
- Set 接口
- 无序性,不允许重复
- TreeSet:基于红黑树实现,查找复杂度 O ( l o g N ) O(logN) O(logN),插入删除复杂度 O ( l o g N ) O(logN) O(logN),支持范围查找
- HashSet:基于哈希表实现,查找复杂度
O
(
1
)
O(1)
O(1),插入删除复杂度
O
(
1
)
O(1)
O(1)
- LinkedHashSet:使用双向链表维护元素的插入顺序,查找复杂度 O ( 1 ) O(1) O(1),插入删除复杂度 O ( 1 ) O(1) O(1)
- 常用操作:add, remove, contains
Set<Integer> tset = new TreeSet<>(); Set<Integer> hset = new HashSet<>(); Set<Integer> lhset = new LinkedHashSet<>();
- List 接口
- 有序性,允许重复
- ArrayList:基于动态数组实现,查找复杂度 O ( 1 ) O(1) O(1),插入删除复杂度 O ( N ) O(N) O(N),自动扩容(1.5)
- LinkedList:基于双向链表实现,查找复杂度 O ( N ) O(N) O(N),插入删除复杂度 O ( 1 ) O(1) O(1)
- Vector:基于动态数组实现,查找复杂度
O
(
1
)
O(1)
O(1),插入删除复杂度
O
(
N
)
O(N)
O(N),并且线程安全(关键方法前加synchronized)
- Stack 类:push, pop, peek, isEmpty
- 常用方法:add, remove, get, set, size, isEmpty, sort, toArray
List<Integer> alist = new ArrayList<>(); List<Integer> llist = new LinkedList<>(); Stack<Integer> stack = new Stack<>();
- Queue 接口
- 先进先出
- 普通队列:Queue 接口
- 双端队列:Deque 接口
- offerFirst, offerLast, pollFirst, pollLast, peekFirst, peekLast, size, isEmpty
- 优先队列:PriorityQueue 类
- 常用方法:offer, poll, peek, size, isEmpty
Queue<Integer> queue = new LinkedList<>(); Deque<Integer> dq = new LinkedList<>(); PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>(){ @Override public int compare(Integer a, Integer b){ return a-b; } });
- Iterator
- 常用方法:hasNext, next
List<T> list = new ArrayList<>(); Iterator<T> it = list.iterator(); while(it.hasNext()){ it.next(); }
- 常用方法:hasNext, next
- Set 接口
- Map 接口
- 键值对,键唯一,不允许重复
- TreeMap:基于红黑树实现,查找复杂度 O ( l o g N ) O(logN) O(logN),插入删除复杂度 O ( l o g N ) O(logN) O(logN)
- HashMap:基于哈希表(在1.8中, 数组+链表/红黑树,8,64)实现,查找复杂度
O
(
1
)
O(1)
O(1),插入删除复杂度
O
(
1
)
O(1)
O(1)
- LinkedHashMap:使用双向队列维护元素的顺序,查找复杂度 O ( 1 ) O(1) O(1),插入删除复杂度 O ( 1 ) O(1) O(1)
- 常用方法:put, remove, get, containsKey, containsValue, entrySet, keySet, values
Map<String, Integer> tmap = new TreeMap<>(); Map<String, Integer> hmap = new HashMap<>(); Map<String, Integer> lhmap = new LinkedHashMap<>();