├── .gitignore ├── 01.Stack ├── 20.有效的括号.cpp ├── 20.有效的括号.java ├── 20.有效的括号.py ├── 84.柱状图中最大的矩形.2.cpp ├── 84.柱状图中最大的矩形.2.java ├── 84.柱状图中最大的矩形.2.py ├── 84.柱状图中最大的矩形.cpp ├── 84.柱状图中最大的矩形.java ├── 84.柱状图中最大的矩形.py ├── Example01.Java ├── Example01.cpp ├── Example01.py ├── Example01_D.cpp ├── Example01_D.java ├── Example01_D.py ├── Example03.cpp ├── Example03.java ├── Example03.py ├── Example04.cpp ├── Example04.java ├── Example04.py ├── Fish.cpp ├── Fish.java ├── Fish.py ├── 右边第一个比我大.cpp ├── 右边第一个比我大.java ├── 右边第一个比我大.py ├── 左边第一个比我大.cpp ├── 左边第一个比我大.java ├── 左边第一个比我大.py ├── 左边第一个比我小.cpp ├── 左边第一个比我小.java └── 左边第一个比我小.py ├── 02.Queue ├── 01.2.TreeLevelOrder.cpp ├── 01.2.TreeLevelOrder.java ├── 01.2.TreeLevelOrder.py ├── 01.3.TreeNext.cpp ├── 01.3.TreeNext.java ├── 01.3.TreeNext.py ├── 01.TreeLevelOrder.cpp ├── 01.TreeLevelOrder.java ├── 01.TreeLevelOrder.py ├── 103.二叉树的锯齿形层序遍历.cpp ├── 103.二叉树的锯齿形层序遍历.java ├── 103.二叉树的锯齿形层序遍历.py ├── 107.二叉树的层序遍历-ii.cpp ├── 107.二叉树的层序遍历-ii.java ├── 107.二叉树的层序遍历-ii.py ├── 1302.层数最深叶子节点的和.cpp ├── 1302.层数最深叶子节点的和.java ├── 1302.层数最深叶子节点的和.py ├── 1696.跳跃游戏-vi.2.cpp ├── 1696.跳跃游戏-vi.2.java ├── 1696.跳跃游戏-vi.2.py ├── 1696.跳跃游戏-vi.cpp ├── 1696.跳跃游戏-vi.java ├── 1696.跳跃游戏-vi.py ├── 239.滑动窗口最大值.cpp ├── 239.滑动窗口最大值.java ├── 239.滑动窗口最大值.py ├── 239.滑动窗口最大值.循环队列.cpp ├── 239.滑动窗口最大值.循环队列.java ├── 239.滑动窗口最大值.循环队列.py ├── 429.n-叉树的层序遍历.cpp ├── 429.n-叉树的层序遍历.java ├── 429.n-叉树的层序遍历.py ├── 559.n-叉树的最大深度.cpp ├── 559.n-叉树的最大深度.java ├── 559.n-叉树的最大深度.py ├── 622.设计循环队列.method1.cpp ├── 622.设计循环队列.method1.java ├── 622.设计循环队列.method1.py ├── 622.设计循环队列.method2.cpp ├── 622.设计循环队列.method2.java ├── 622.设计循环队列.method2.py ├── 637.二叉树的层平均值.cpp ├── 637.二叉树的层平均值.java ├── 637.二叉树的层平均值.py ├── 662.二叉树最大宽度.cpp ├── 662.二叉树最大宽度.java ├── 662.二叉树最大宽度.java.orig ├── 662.二叉树最大宽度.py ├── P1886.cc ├── P1886.java └── README.md ├── 03.HeapAndPriorityQueue ├── 1642.可以到达的最远建筑.cpp ├── 1642.可以到达的最远建筑.java ├── 1642.可以到达的最远建筑.py ├── 1705.吃苹果的最大数目.cpp ├── 1705.吃苹果的最大数目.java ├── 1705.吃苹果的最大数目.py ├── 23.合并k个升序链表.cpp ├── 23.合并k个升序链表.java ├── 23.合并k个升序链表.py ├── 295.数据流的中位数.cpp ├── 295.数据流的中位数.java ├── 295.数据流的中位数.py ├── 347.前-k-个高频元素.cpp ├── 347.前-k-个高频元素.java ├── 347.前-k-个高频元素.py ├── 373.查找和最小的k对数字.cpp ├── 373.查找和最小的k对数字.java ├── 373.查找和最小的k对数字.py ├── 692.前k个高频单词.cpp ├── 692.前k个高频单词.java ├── 692.前k个高频单词.py ├── 743.网络延迟时间.cpp ├── 743.网络延迟时间.java ├── 743.网络延迟时间.py ├── 871.最低加油次数.cpp ├── 871.最低加油次数.java ├── 871.最低加油次数.py ├── 973.最接近原点的-k-个点.cpp ├── 973.最接近原点的-k-个点.java ├── 973.最接近原点的-k-个点.py ├── README.md ├── heap.cpp ├── heap.java ├── heap.py ├── 剑指Offer40.最小的k个数.cpp ├── 剑指Offer40.最小的k个数.java ├── 剑指Offer40.最小的k个数.kth.cpp ├── 剑指Offer40.最小的k个数.kth.java ├── 剑指Offer40.最小的k个数.kth.py ├── 剑指Offer40.最小的k个数.py ├── 剑指Offer40.最小的k个数.使用堆.cpp ├── 剑指Offer40.最小的k个数.使用堆.java ├── 剑指Offer40.最小的k个数.使用堆.py ├── 数据流中位数.cpp ├── 数据流中位数.java └── 数据流中位数.py ├── 04.LinkedList ├── 707.设计链表.cpp ├── 707.设计链表.py ├── DesignLinkedList.java ├── ans.cpp ├── ans.java └── ans.py ├── 05.LinkedList ├── 141.环形链表.cpp ├── 141.环形链表.java ├── 141.环形链表.py ├── 142.环形链表-ii.cpp ├── 142.环形链表-ii.java ├── 142.环形链表-ii.py ├── 143.重排链表.cpp ├── 143.重排链表.java ├── 143.重排链表.py ├── 19.删除链表的倒数第-n-个结点.cpp ├── 19.删除链表的倒数第-n-个结点.java ├── 19.删除链表的倒数第-n-个结点.py ├── 203.移除链表元素.cpp ├── 203.移除链表元素.java ├── 203.移除链表元素.py ├── 206.反转链表.cpp ├── 206.反转链表.java ├── 206.反转链表.py ├── 21.合并两个有序链表.cpp ├── 21.合并两个有序链表.java ├── 21.合并两个有序链表.py ├── 23.合并k个升序链表.cpp ├── 23.合并k个升序链表.java ├── 23.合并k个升序链表.py ├── 24.两两交换链表中的节点.cpp ├── 24.两两交换链表中的节点.java ├── 24.两两交换链表中的节点.py ├── 25.k-个一组翻转链表.cpp ├── 25.k-个一组翻转链表.java ├── 25.k-个一组翻转链表.py ├── 25.逆向k个一组翻转链表.cpp ├── 25.逆向k个一组翻转链表.java ├── 25.逆向k个一组翻转链表.py ├── 82.删除排序链表中的重复元素-ii.cpp ├── 82.删除排序链表中的重复元素-ii.java ├── 82.删除排序链表中的重复元素-ii.py ├── 83.删除排序链表中的重复元素.cpp ├── 83.删除排序链表中的重复元素.java ├── 83.删除排序链表中的重复元素.py ├── splitList.2.java ├── splitList.3.java ├── splitList.cpp ├── splitList.java └── splitList.py ├── 06.Tree ├── 100.相同的树.cpp ├── 100.相同的树.java ├── 100.相同的树.py ├── 105.从前序与中序遍历序列构造二叉树.cpp ├── 105.从前序与中序遍历序列构造二叉树.java ├── 105.从前序与中序遍历序列构造二叉树.py ├── 112.路径总和.cpp ├── 112.路径总和.java ├── 112.路径总和.py ├── 113.路径总和-ii.cpp ├── 113.路径总和-ii.java ├── 113.路径总和-ii.py ├── 144.二叉树的前序遍历.cpp ├── 144.二叉树的前序遍历.java ├── 144.二叉树的前序遍历.morris.cpp ├── 144.二叉树的前序遍历.morris.java ├── 144.二叉树的前序遍历.morris.py ├── 144.二叉树的前序遍历.py ├── 144.二叉树的前序遍历.stack.cpp ├── 144.二叉树的前序遍历.stack.java ├── 144.二叉树的前序遍历.stack.py ├── 145.二叉树的后序遍历.morris.cpp ├── 145.二叉树的后序遍历.morris.java ├── 145.二叉树的后序遍历.morris.py ├── 145.二叉树的后序遍历.recursive.cpp ├── 145.二叉树的后序遍历.recursive.java ├── 145.二叉树的后序遍历.recursive.py ├── 145.二叉树的后序遍历.stack.cpp ├── 145.二叉树的后序遍历.stack.java ├── 145.二叉树的后序遍历.stack.py ├── 236.二叉树的最近公共祖先.py ├── 236.二叉树的最近公共祖先.前序.cpp ├── 236.二叉树的最近公共祖先.前序.java ├── 236.二叉树的最近公共祖先.前序.py ├── 236.二叉树的最近公共祖先.后序.cpp ├── 236.二叉树的最近公共祖先.后序.java ├── 236.二叉树的最近公共祖先.后序.py ├── 450.删除二叉搜索树中的节点.cpp ├── 450.删除二叉搜索树中的节点.java ├── 450.删除二叉搜索树中的节点.py ├── 501.二叉搜索树中的众数.cpp ├── 501.二叉搜索树中的众数.java ├── 501.二叉搜索树中的众数.py ├── 572.另一个树的子树.cpp ├── 572.另一个树的子树.java ├── 572.另一个树的子树.py ├── 700.二叉搜索树中的搜索.cpp ├── 700.二叉搜索树中的搜索.java ├── 700.二叉搜索树中的搜索.py ├── 701.二叉搜索树中的插入操作.cpp ├── 701.二叉搜索树中的插入操作.java ├── 701.二叉搜索树中的插入操作.py ├── 783.二叉搜索树节点最小距离.cpp ├── 783.二叉搜索树节点最小距离.java ├── 783.二叉搜索树节点最小距离.py ├── 876.链表的中间结点.cpp ├── 876.链表的中间结点.java ├── 876.链表的中间结点.py ├── 94.二叉树的中序遍历.1.cpp ├── 94.二叉树的中序遍历.1.java ├── 94.二叉树的中序遍历.1.py ├── 94.二叉树的中序遍历.morris.cpp ├── 94.二叉树的中序遍历.morris.java ├── 94.二叉树的中序遍历.morris.py ├── 94.二叉树的中序遍历.stack.cpp ├── 94.二叉树的中序遍历.stack.java ├── 94.二叉树的中序遍历.stack.py ├── 98.验证二叉搜索树.1.cpp ├── 98.验证二叉搜索树.1.java ├── 98.验证二叉搜索树.1.py ├── 98.验证二叉搜索树.2.cpp ├── 98.验证二叉搜索树.2.java ├── 98.验证二叉搜索树.2.py ├── 98.验证二叉搜索树.中序.cpp ├── 98.验证二叉搜索树.中序.java ├── 98.验证二叉搜索树.中序.py ├── 98.验证二叉搜索树.后序.cpp ├── 98.验证二叉搜索树.后序.java ├── 98.验证二叉搜索树.后序.py ├── 99.恢复二叉搜索树.2.cpp ├── 99.恢复二叉搜索树.2.java ├── 99.恢复二叉搜索树.2.py ├── 99.恢复二叉搜索树.3.cpp ├── 99.恢复二叉搜索树.3.java ├── 99.恢复二叉搜索树.3.py ├── 99.恢复二叉搜索树.cpp ├── 99.恢复二叉搜索树.java └── 99.恢复二叉搜索树.py ├── 07.UF ├── 1168.大楼通网.cpp ├── 1168.大楼通网.java ├── 1168.大楼通网.py ├── 130.被围绕的区域.cpp ├── 130.被围绕的区域.java ├── 130.被围绕的区域.py ├── 200.岛屿数量.cpp ├── 200.岛屿数量.java ├── 200.岛屿数量.py ├── 399.除法求值.cpp ├── 399.除法求值.java ├── 399.除法求值.py ├── 547.省份数量.cpp ├── 547.省份数量.java ├── 547.省份数量.py ├── 765.情侣牵手.cpp ├── 765.情侣牵手.java ├── 765.情侣牵手.py ├── 839.相似字符串组.cpp ├── 839.相似字符串组.java ├── 839.相似字符串组.py ├── P1287.cpp ├── P1287.java ├── P1287.py ├── T1260.cpp ├── T1260.java ├── T1260.py ├── 并查集模板.cpp ├── 并查集模板.java ├── 并查集模板.py └── 最小生成树的代价.md ├── 08.Sort ├── 136.只出现一次的数字.bitops.cpp ├── 136.只出现一次的数字.cpp ├── 136.只出现一次的数字.java ├── 136.只出现一次的数字.py ├── 148.排序链表.cpp ├── 148.排序链表.java ├── 148.排序链表.py ├── 148.排序链表.qsort.cpp ├── 148.排序链表.qsort.java ├── 148.排序链表.qsort.py ├── 21.合并两个有序链表.cpp ├── 21.合并两个有序链表.java ├── 21.合并两个有序链表.py ├── 283.移动零.cpp ├── 283.移动零.java ├── 283.移动零.py ├── 315.计算右侧小于当前元素的个数.cpp ├── 315.计算右侧小于当前元素的个数.java ├── 315.计算右侧小于当前元素的个数.py ├── 4.寻找两个正序数组的中位数.cpp ├── 4.寻找两个正序数组的中位数.java ├── 4.寻找两个正序数组的中位数.py ├── 75.颜色分类.mergesort.cpp ├── 75.颜色分类.mergesort.java ├── 75.颜色分类.mergesort.py ├── 75.颜色分类.qsort.cpp ├── 75.颜色分类.qsort.java ├── 75.颜色分类.qsort.py ├── 75.颜色分类.三路快排.cpp ├── 75.颜色分类.三路快排.java ├── 75.颜色分类.三路快排.py ├── 786.第k个数.cpp ├── 786.第k个数.heap.cpp ├── 786.第k个数.heap.java ├── 786.第k个数.heap.py ├── 786.第k个数.java ├── 786.第k个数.py ├── 88.合并两个有序数组.cpp ├── 88.合并两个有序数组.java ├── 88.合并两个有序数组.py ├── mergeSort.cpp ├── mergeSort.java ├── mergeSort.py ├── reversePairs.cpp ├── reversePairs.java ├── reversePairs.py ├── seqNumber.cpp ├── seqNumber.java ├── seqNumber.py ├── 剑指Offer40.最小的k个数.kth.cpp ├── 剑指Offer40.最小的k个数.kth.java └── 剑指Offer40.最小的k个数.kth.py ├── 09.BinarySearch ├── 153.寻找旋转排序数组中的最小值.cpp ├── 153.寻找旋转排序数组中的最小值.java ├── 153.寻找旋转排序数组中的最小值.py ├── 154.寻找旋转排序数组中的最小值-ii.cpp ├── 154.寻找旋转排序数组中的最小值-ii.java ├── 154.寻找旋转排序数组中的最小值-ii.left.java ├── 154.寻找旋转排序数组中的最小值-ii.py ├── 209.长度最小的子数组.cpp ├── 209.长度最小的子数组.java ├── 209.长度最小的子数组.py ├── 33.搜索旋转排序数组.2.cpp ├── 33.搜索旋转排序数组.2.java ├── 33.搜索旋转排序数组.2.py ├── 33.搜索旋转排序数组.cpp ├── 33.搜索旋转排序数组.java ├── 33.搜索旋转排序数组.py ├── 34.在排序数组中查找元素的第一个和最后一个位置.cpp ├── 34.在排序数组中查找元素的第一个和最后一个位置.java ├── 34.在排序数组中查找元素的第一个和最后一个位置.py ├── 35.搜索插入位置.cpp ├── 35.搜索插入位置.java ├── 35.搜索插入位置.py ├── 53.最大子序和.cpp ├── 53.最大子序和.java ├── 53.最大子序和.py ├── 617._子数组的最大平均值_II.java ├── 69.x-的平方根.cpp ├── 69.x-的平方根.java ├── 69.x-的平方根.py ├── 69.数组中数值和下标相等的元素.2.cpp ├── 69.数组中数值和下标相等的元素.2.java ├── 69.数组中数值和下标相等的元素.2.py ├── 69.数组中数值和下标相等的元素.cpp ├── 69.数组中数值和下标相等的元素.java ├── 69.数组中数值和下标相等的元素.py ├── 76.最小覆盖子串.cpp ├── 76.最小覆盖子串.java ├── 76.最小覆盖子串.py ├── 76.最小覆盖子串.双指针.cpp ├── 81.搜索旋转排序数组-ii.2.cpp ├── 81.搜索旋转排序数组-ii.2.java ├── 81.搜索旋转排序数组-ii.2.py ├── 81.搜索旋转排序数组-ii.cpp ├── 81.搜索旋转排序数组-ii.java ├── 81.搜索旋转排序数组-ii.py ├── 852.山脉数组的峰顶索引.cpp ├── 852.山脉数组的峰顶索引.java ├── 852.山脉数组的峰顶索引.py ├── 868._子数组的最大平均值.2.cpp ├── 868._子数组的最大平均值.2.java ├── 868._子数组的最大平均值.2.py ├── 868._子数组的最大平均值.cpp ├── 868._子数组的最大平均值.java ├── 868._子数组的最大平均值.py ├── BinarySearch.java ├── MaxSumLengthSmallerK.cpp ├── MaxSumLengthSmallerK.java ├── MaxSumLengthSmallerK.py ├── T1560.2.cpp ├── T1560.2.java ├── T1560.2.py ├── T1560.cpp ├── T1560.java ├── T1560.py ├── T1562.cpp ├── T1562.java └── T1562.py ├── 10.DoublePointer ├── 209.长度最小的子数组.cpp ├── 209.长度最小的子数组.java ├── 209.长度最小的子数组.py ├── 3.无重复字符的最长子串.cpp ├── 3.无重复字符的最长子串.java ├── 3.无重复字符的最长子串.py ├── 30.串联所有单词的子串.fix.window.cpp ├── 30.串联所有单词的子串.fix.window.java ├── 30.串联所有单词的子串.fix.window.py ├── 386.最多有k个不同字符的最长子字符串.cpp ├── 386.最多有k个不同字符的最长子字符串.java ├── 386.最多有k个不同字符的最长子字符串.py ├── 424.替换后的最长重复字符.cpp ├── 424.替换后的最长重复字符.java ├── 424.替换后的最长重复字符.py ├── 53.最大子序和.cpp ├── 53.最大子序和.java ├── 53.最大子序和.py ├── 567.字符串的排列.array.hash.java ├── 567.字符串的排列.fix.window.cpp ├── 567.字符串的排列.fix.window.java ├── 567.字符串的排列.fix.window.py ├── 64.字符流中第一个只出现一次的字符.cpp ├── 64.字符流中第一个只出现一次的字符.java ├── 64.字符流中第一个只出现一次的字符.py ├── 713.乘积小于k的子数组.cpp ├── 713.乘积小于k的子数组.java ├── 713.乘积小于k的子数组.py ├── 76.最小覆盖子串.cpp ├── 76.最小覆盖子串.java ├── 76.最小覆盖子串.py ├── 845.数组中的最长山脉.cpp ├── 845.数组中的最长山脉.java ├── 845.数组中的最长山脉.py ├── 904.水果成篮.cpp ├── 904.水果成篮.java ├── 904.水果成篮.py ├── 921.最长子数组和为k.cpp ├── 921.最长子数组和为k.java ├── 921.最长子数组和为k.py ├── 928.最多有两个不同字符的最长子串.java ├── 992.k-个不同整数的子数组.minus.java └── 992.k-个不同整数的子数组.small.large.java ├── 11.Greedy ├── 1024.视频拼接.cpp ├── 1024.视频拼接.java ├── 1024.视频拼接.py ├── 11.盛最多水的容器.cpp ├── 11.盛最多水的容器.java ├── 11.盛最多水的容器.py ├── 134.加油站.2.cpp ├── 134.加油站.2.java ├── 134.加油站.2.py ├── 134.加油站.cpp ├── 134.加油站.java ├── 134.加油站.py ├── 42.接雨水.cpp ├── 42.接雨水.java ├── 42.接雨水.py ├── 435.无重叠区间.1.cpp ├── 435.无重叠区间.1.java ├── 435.无重叠区间.1.py ├── 435.无重叠区间.2.cpp ├── 435.无重叠区间.2.java ├── 435.无重叠区间.2.py ├── 45.跳跃游戏-ii.cpp ├── 45.跳跃游戏-ii.java ├── 45.跳跃游戏-ii.py ├── 452.用最少数量的箭引爆气球.cpp ├── 452.用最少数量的箭引爆气球.java ├── 452.用最少数量的箭引爆气球.py ├── 53.最大子序和.cpp ├── 53.最大子序和.java ├── 53.最大子序和.py ├── 55.跳跃游戏.cpp ├── 55.跳跃游戏.java ├── 55.跳跃游戏.py ├── 56.合并区间.cpp ├── 56.合并区间.java ├── 56.合并区间.py ├── 763.划分字母区间.cpp ├── 763.划分字母区间.java ├── 763.划分字母区间.py ├── 918.环形子数组的最大和.cpp ├── 918.环形子数组的最大和.java ├── 918.环形子数组的最大和.py ├── nonOverlap.1.cpp ├── nonOverlap.1.java ├── nonOverlap.1.py ├── nonOverlap.2.cpp ├── nonOverlap.2.java └── nonOverlap.2.py ├── 12.BackTrack ├── 17.电话号码的字母组合.cpp ├── 17.电话号码的字母组合.java ├── 216.组合总和-iii.cpp ├── 216.组合总和-iii.java ├── 216.组合总和-iii.py ├── 26.删除有序数组中的重复项.cpp ├── 26.删除有序数组中的重复项.java ├── 26.删除有序数组中的重复项.py ├── 39.组合总和.cpp ├── 39.组合总和.java ├── 39.组合总和.py ├── 40.组合总和-ii.java ├── 46.全排列.2.cpp ├── 46.全排列.2.java ├── 46.全排列.2.py ├── 46.全排列.3.cpp ├── 46.全排列.3.java ├── 46.全排列.cpp ├── 46.全排列.java ├── 46.全排列.py ├── 47.全排列-ii.1.cpp ├── 47.全排列-ii.1.java ├── 47.全排列-ii.1.py ├── 47.全排列-ii.cpp ├── 47.全排列-ii.java ├── 47.全排列-ii.py ├── 77.组合.cpp ├── 77.组合.java ├── 77.组合.py ├── 78.子集.cpp ├── 78.子集.java ├── 78.子集.py ├── 784.字母大小写全排列.cpp ├── 784.字母大小写全排列.java ├── 784.字母大小写全排列.py ├── 90.子集-ii.1.cpp ├── 90.子集-ii.1.java ├── 90.子集-ii.2.java ├── 90.子集-ii.cpp └── 90.子集-ii.java ├── 13.DFS.BFS ├── 1091.二进制矩阵中的最短路径.cpp ├── 1091.二进制矩阵中的最短路径.java ├── 1091.二进制矩阵中的最短路径.py ├── 120.三角形最小路径和.cpp ├── 120.三角形最小路径和.java ├── 120.三角形最小路径和.py ├── 130.被围绕的区域.cpp ├── 130.被围绕的区域.java ├── 130.被围绕的区域.py ├── 131.分割回文串.cpp ├── 131.分割回文串.java ├── 131.分割回文串.py ├── 133.克隆图.cpp ├── 133.克隆图.java ├── 133.克隆图.py ├── 200.岛屿数量.cpp ├── 200.岛屿数量.java ├── 200.岛屿数量.py ├── 22.DP │ ├── 22.括号生成.cpp │ ├── 22.括号生成.java │ └── 22.括号生成.py ├── 22.两段击 │ ├── 22.括号生成.cpp │ ├── 22.括号生成.java │ └── 22.括号生成.py ├── 22.回溯 │ ├── 22.括号生成.cpp │ ├── 22.括号生成.java │ └── 22.括号生成.py ├── 22.队列 │ ├── 22.括号生成.cpp │ ├── 22.括号生成.java │ └── 22.括号生成.py ├── 279.完全平方数.java ├── 322.零钱兑换.cpp ├── 322.零钱兑换.java ├── 322.零钱兑换.py ├── 547.省份数量.cpp ├── 547.省份数量.java ├── 547.省份数量.py ├── 713.乘积小于k的子数组.cpp ├── 713.乘积小于k的子数组.java ├── 713.乘积小于k的子数组.py ├── 778.水位上升的泳池中游泳.cpp ├── 778.水位上升的泳池中游泳.java ├── 778.水位上升的泳池中游泳.py ├── 783._Minimum_Risk_Path.cpp ├── 783._Minimum_Risk_Path.java ├── 783._Minimum_Risk_Path.py ├── P3984.cpp ├── P3984.java ├── P3984.py ├── Solution.class ├── 八皇后.cpp ├── 八皇后.java └── 八皇后.py ├── 14.DP ├── 1349.参加考试的最大学生数.cpp ├── 1349.参加考试的最大学生数.java ├── 1349.参加考试的最大学生数.py ├── 1799.n-次操作后的最大分数和.cpp ├── 1799.n-次操作后的最大分数和.java ├── 1799.n-次操作后的最大分数和.py ├── 198.打家劫舍.cpp ├── 198.打家劫舍.java ├── 198.打家劫舍.py ├── 213.打家劫舍-ii.cpp ├── 213.打家劫舍-ii.java ├── 213.打家劫舍-ii.py ├── 322.零钱兑换.cpp ├── 322.零钱兑换.java ├── 322.零钱兑换.py ├── 337.打家劫舍-iii.cpp ├── 337.打家劫舍-iii.java ├── 337.打家劫舍-iii.py ├── 416.分割等和子集.cpp ├── 416.分割等和子集.java ├── 416.分割等和子集.py ├── 494.目标和.backtrace.cpp ├── 494.目标和.backtrace.java ├── 494.目标和.backtrace.py ├── 494.目标和.cpp ├── 494.目标和.java ├── 494.目标和.py ├── 543.二叉树的直径.cpp ├── 543.二叉树的直径.java ├── 543.二叉树的直径.py ├── 837.新-21-点.cpp ├── 837.新-21-点.java ├── 837.新-21-点.py ├── 87.扰乱字符串.cpp ├── 87.扰乱字符串.java ├── 87.扰乱字符串.py ├── acwing.01.cpp ├── acwing.01.java ├── acwing.01.py ├── acwing.full.cpp ├── acwing.full.java └── acwing.full.py ├── 15.StrStr ├── 214.最短回文串.cpp ├── 214.最短回文串.java ├── 214.最短回文串.py ├── 28.实现-str-str.bm.cpp ├── 28.实现-str-str.bm.java ├── 28.实现-str-str.bm.py ├── 28.实现-str-str.cpp ├── 28.实现-str-str.java ├── 28.实现-str-str.kmp.cpp ├── 28.实现-str-str.kmp.java ├── 28.实现-str-str.kmp.py ├── 28.实现-str-str.kmp2.cpp ├── 28.实现-str-str.kmp2.java ├── 28.实现-str-str.kmp2.py ├── 28.实现-str-str.pmt.cpp ├── 28.实现-str-str.pmt.java ├── 28.实现-str-str.pmt.py ├── 28.实现-str-str.py ├── 28.实现-str-str.sunday.cpp ├── 28.实现-str-str.sunday.java ├── 28.实现-str-str.sunday.py ├── 459.重复的子字符串.cpp ├── 459.重复的子字符串.java ├── 459.重复的子字符串.mod.cpp ├── 459.重复的子字符串.mod.java ├── 459.重复的子字符串.mod.py ├── 459.重复的子字符串.next.cpp ├── 459.重复的子字符串.next.java ├── 459.重复的子字符串.next.py ├── 459.重复的子字符串.py ├── BF.C ├── BM.C ├── KMP.C ├── Sunday.C ├── next.cpp ├── next.java ├── next.py ├── pmt.cpp ├── pmt.java └── pmt.py ├── 16.Rectangle ├── 669.修剪二叉搜索树.cpp ├── 669.修剪二叉搜索树.java ├── 669.修剪二叉搜索树.py ├── 84.柱状图中最大的矩形.cpp ├── 84.柱状图中最大的矩形.dp.cpp ├── 84.柱状图中最大的矩形.dp.java ├── 84.柱状图中最大的矩形.dp.py ├── 84.柱状图中最大的矩形.dq.cpp ├── 84.柱状图中最大的矩形.dq.java ├── 84.柱状图中最大的矩形.dq.py ├── 84.柱状图中最大的矩形.dq.seg.cpp ├── 84.柱状图中最大的矩形.dq.seg.java ├── 84.柱状图中最大的矩形.dq.seg.py ├── 84.柱状图中最大的矩形.dq.st.cpp ├── 84.柱状图中最大的矩形.dq.st.java ├── 84.柱状图中最大的矩形.dq.st.py ├── 84.柱状图中最大的矩形.dq2.cpp ├── 84.柱状图中最大的矩形.dq2.java ├── 84.柱状图中最大的矩形.dq2.py ├── 84.柱状图中最大的矩形.java ├── 84.柱状图中最大的矩形.py ├── 84.柱状图中最大的矩形.segtree.cpp ├── 84.柱状图中最大的矩形.segtree.java ├── 84.柱状图中最大的矩形.segtree.py ├── 84.柱状图中最大的矩形.st.cpp ├── 84.柱状图中最大的矩形.st.java ├── 84.柱状图中最大的矩形.st.py ├── 85.最大矩形.cpp ├── 85.最大矩形.java └── 85.最大矩形.py ├── 17.Subset ├── 78.子集.BFS.cpp ├── 78.子集.BFS.java ├── 78.子集.BFS.py ├── 78.子集.binary.cpp ├── 78.子集.binary.java ├── 78.子集.binary.py ├── 78.子集.dq.cpp ├── 78.子集.dq.java ├── 78.子集.dq.py ├── 787.k-站中转内最便宜的航班.cpp ├── 787.k-站中转内最便宜的航班.java ├── 787.k-站中转内最便宜的航班.py ├── 90.子集-ii.BFS.2.cpp ├── 90.子集-ii.BFS.2.java ├── 90.子集-ii.BFS.2.py ├── 90.子集-ii.BFS.cpp ├── 90.子集-ii.BFS.java ├── 90.子集-ii.BFS.py ├── 90.子集-ii.binary.cpp ├── 90.子集-ii.binary.java ├── 90.子集-ii.binary.py ├── 90.子集-ii.dq.cpp ├── 90.子集-ii.dq.java └── 90.子集-ii.dq.py ├── 18.Words ├── 126.单词接龙-ii.cpp ├── 127.单词接龙.BF.java ├── 127.单词接龙.BFS.cpp ├── 127.单词接龙.BFS.java ├── 127.单词接龙.BFS.py ├── 127.单词接龙.D.BFS.cpp ├── 127.单词接龙.D.BFS.java ├── 127.单词接龙.D.BFS.py ├── 127.单词接龙.DFS.Q.cpp ├── 127.单词接龙.DFS.Q.java ├── 127.单词接龙.DFS.Q.py ├── 127.单词接龙.DFS.cpp ├── 127.单词接龙.DFS.java ├── 127.单词接龙.DFS.py ├── 127.单词接龙.Dijstra.cpp ├── 127.单词接龙.Dijstra.java ├── 127.单词接龙.Dijstra.py ├── 743.网络延迟时间.cpp ├── 743.网络延迟时间.java └── 743.网络延迟时间.py ├── 19.Efforts ├── 1631.最小体力消耗路径.Dijkstra.java ├── 1631.最小体力消耗路径.bf.java ├── 1631.最小体力消耗路径.binarySearch.java ├── 1631.最小体力消耗路径.binarySearch_bfs.java ├── 1631.最小体力消耗路径.binarySearch_uf.java ├── 1631.最小体力消耗路径.uf.java └── 64.最小路径和.java ├── 20.Braces ├── 22.括号生成.java ├── 32.最长有效括号.DoublePointer.java ├── 32.最长有效括号.dp.java ├── 32.最长有效括号.maxSum.java ├── 32.最长有效括号.overlapped.ranges.java ├── 32.最长有效括号.overlapped.ranges.no.sort.java ├── 32.最长有效括号.sort.java ├── 32.最长有效括号.sort.no.sort.java └── 32.最长有效括号.stack.java ├── 21.Meets ├── 903.cpp ├── 903.java ├── 903.py ├── 919.会议室II.PQ.java ├── 919.会议室II.cpp ├── 919.会议室II.差分.java ├── 919.会议室II.差分2.java ├── 919.会议室II.差分3.java ├── 920.会议室.java └── ans.java ├── 22.DS ├── 155.最小栈.java ├── 225.用队列实现栈.java └── 946.验证栈序列.java ├── 24.MyInterView ├── 105.从前序与中序遍历序列构造二叉树.cpp ├── 105.从前序与中序遍历序列构造二叉树.hash.cpp ├── 105.从前序与中序遍历序列构造二叉树.hash.java ├── 105.从前序与中序遍历序列构造二叉树.hash.py ├── 105.从前序与中序遍历序列构造二叉树.java ├── 105.从前序与中序遍历序列构造二叉树.py ├── 124.二叉树中的最大路径和.java ├── 136.只出现一次的数字.java ├── 137.只出现一次的数字-ii.2.java ├── 137.只出现一次的数字-ii.java ├── 617.合并二叉树.java ├── 679.24-点游戏.java └── 876.链表的中间结点.java ├── 25.Templates └── c++模板.md ├── README.md ├── genurl.sh └── remove_comment.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | code 3 | -------------------------------------------------------------------------------- /01.Stack/20.有效的括号.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * [20] 有效的括号 4 | */ 5 | 6 | class Solution { 7 | public: 8 | bool isValid(string s) { 9 | if (s.length() & 0x01) { 10 | return false; 11 | } 12 | stack t; 13 | for (auto c : s) { 14 | if (c == '{' || c == '[' || c == '(') { 15 | t.push(c); 16 | } else if (c == ')') { 17 | if (t.empty() || t.top() != '(') { 18 | return false; 19 | } 20 | t.pop(); 21 | } else if (c == '}') { 22 | if (t.empty() || t.top() != '{') { 23 | return false; 24 | } 25 | t.pop(); 26 | } else if (c == ']') { 27 | if (t.empty() || t.top() != '[') { 28 | return false; 29 | } 30 | t.pop(); 31 | } else { 32 | return false; 33 | } 34 | } 35 | 36 | return t.empty(); 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /01.Stack/20.有效的括号.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 测试平台链接:https://leetcode-cn.com/problems/valid-parentheses/ 3 | * [20] 有效的括号 4 | */ 5 | 6 | class Solution { 7 | public boolean isValid(String s) { 8 | if (s == null || s.length() == 0) { 9 | return true; 10 | } 11 | if (s.length() % 2 == 1) { 12 | return false; 13 | } 14 | Stack t = new Stack(); 15 | 16 | for (int i = 0; i < s.length(); i++) { 17 | char c = s.charAt(i); 18 | if (c == '{' || c == '(' || c == '[') { 19 | t.push(c); 20 | } else if (c == '}') { 21 | if (t.empty() || t.peek() != '{') { 22 | return false; 23 | } 24 | t.pop(); 25 | } else if (c == ']') { 26 | if (t.empty() || t.peek() != '[') { 27 | return false; 28 | } 29 | t.pop(); 30 | } else if (c == ')') { 31 | if (t.empty() || t.peek() != '(') { 32 | return false; 33 | } 34 | t.pop(); 35 | } else { 36 | return false; 37 | } 38 | } 39 | 40 | return t.empty(); 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /01.Stack/20.有效的括号.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # 4 | # [20] 有效的括号 5 | # 6 | 7 | class Solution(object): 8 | def isValid(self, s): 9 | """ 10 | :type s: str 11 | :rtype: bool 12 | """ 13 | if not s or len(s) == 0: 14 | return True 15 | 16 | if len(s) % 2 == 1: 17 | return False 18 | 19 | t = [] 20 | 21 | for c in s: 22 | if c == '[' or c == '{' or c == '(': 23 | t.append(c) 24 | elif c == ']': 25 | last = t.pop() if t else '#' 26 | if last != '[': 27 | return False 28 | elif c == '}': 29 | last = t.pop() if t else '#' 30 | if last != '{': 31 | return False 32 | elif c == ')': 33 | last = t.pop() if t else '#' 34 | if last != '(': 35 | return False 36 | else: 37 | return False 38 | 39 | return not t 40 | 41 | -------------------------------------------------------------------------------- /01.Stack/Example01.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | class Solution: 4 | def isValid(self, s): 5 | if not s or len(s) == 0: 6 | return True 7 | if len(s) % 2 == 1: 8 | return False 9 | 10 | t = [] 11 | for c in s: 12 | if c == '(': 13 | t.append(c) 14 | elif c == ')': 15 | if len(t) == 0: 16 | return False 17 | t.pop() 18 | else: 19 | return False 20 | return len(t) == 0 21 | 22 | solution = Solution() 23 | 24 | assert solution.isValid("") 25 | assert not solution.isValid("(") 26 | assert not solution.isValid(")") 27 | 28 | assert solution.isValid("()") 29 | assert not solution.isValid("((") 30 | assert not solution.isValid("))") 31 | assert not solution.isValid(")(") 32 | 33 | assert not solution.isValid("())") 34 | assert not solution.isValid("(((") 35 | assert not solution.isValid(")))") 36 | assert not solution.isValid(")()") 37 | 38 | assert solution.isValid("()()") 39 | assert solution.isValid("(())") 40 | assert not solution.isValid("))((") 41 | 42 | assert solution.isValid("()()()") 43 | assert solution.isValid("((()))") 44 | assert solution.isValid("()(())") 45 | assert not solution.isValid("()(()(") -------------------------------------------------------------------------------- /01.Stack/Example03.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | using namespace std; 21 | 22 | vector findRightSmall(vector &A) { 23 | if (A.empty()) { 24 | return {}; 25 | } 26 | // 结果数组 27 | vector ans(A.size()); 28 | 29 | // 注意,栈中的元素记录的是下标 30 | stack t; 31 | 32 | for (size_t i = 0; i < A.size(); i++) { 33 | const int x = A[i]; 34 | // 每个元素都向左遍历栈中的元素完成消除动作 35 | while (!t.empty() && A[t.top()] > x) { 36 | // 消除的时候,记录一下被谁消除了 37 | ans[t.top()] = i; 38 | // 消除时候,值更大的需要从栈中消失 39 | t.pop(); 40 | } 41 | // 剩下的入栈 42 | t.push(i); 43 | } 44 | // 栈中剩下的元素,由于没有人能消除他们,因此,只能将结果设置为-1。 45 | while (!t.empty()) { 46 | ans[t.top()] = -1; 47 | t.pop(); 48 | } 49 | 50 | return ans; 51 | } 52 | 53 | // 测试代码 54 | void ASSERT_EQ(vector A, vector B) { 55 | auto C = findRightSmall(B); 56 | assert(A == C); 57 | } 58 | 59 | int main(void) { 60 | ASSERT_EQ({1, -1}, {5, 2}); 61 | ASSERT_EQ({5, 5, 5, 4, 5, -1, -1}, {1, 2, 4, 9, 4, 0, 5}); 62 | return 0; 63 | } -------------------------------------------------------------------------------- /01.Stack/Example03.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.Stack; 3 | 4 | class Solution { 5 | public static int[] findRightSmall(int[] A) { 6 | // 结果数组 7 | int[] ans = new int[A.length]; 8 | // 注意,栈中的元素记录的是下标 9 | Stack t = new Stack<>(); 10 | 11 | for (int i = 0; i < A.length; i++) { 12 | final int x = A[i]; 13 | // 每个元素都向左遍历栈中的元素完成消除动作 14 | while (!t.empty() && A[t.peek()] > x) { 15 | // 消除的时候,记录一下被谁消除了 16 | ans[t.peek()] = i; 17 | // 消除时候,值更大的需要从栈中消失 18 | t.pop(); 19 | } 20 | // 剩下的入栈 21 | t.push(i); 22 | } 23 | // 栈中剩下的元素,由于没有人能消除他们,因此,只能将结果设置为-1。 24 | while (!t.empty()) { 25 | ans[t.peek()] = -1; 26 | t.pop(); 27 | } 28 | 29 | return ans; 30 | } 31 | } 32 | 33 | // 测试代码 34 | class Example03 { 35 | public static void main(String[] args) { 36 | assert(Arrays.equals(new int[]{1,-1}, Solution.findRightSmall(new int[]{5,4}))); 37 | assert(Arrays.equals(new int[]{5, 5, 5, 4, 5, -1, -1}, Solution.findRightSmall(new int[]{1, 2, 4, 9, 4, 0, 5}))); 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /01.Stack/Example03.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | class Solution: 4 | def findRightSmall(self, A): 5 | if not A or len(A) == 0: 6 | return [] 7 | 8 | # 结果数组 9 | ans =[0] * len(A) 10 | 11 | # 注意,栈中的元素记录的是下标 12 | t = [] 13 | 14 | for i in range(0, len(A)): 15 | x = A[i] 16 | # 每个元素都向左遍历栈中的元素完成消除动作 17 | while len(t) > 0 and A[t[-1]] > x: 18 | # 消除的时候,记录一下被谁消除了 19 | ans[t[-1]] = i 20 | # 消除时候,值更大的需要从栈中消失 21 | t.pop() 22 | 23 | # 剩下的入栈 24 | t.append(i) 25 | 26 | # 栈中剩下的元素,由于没有人能消除他们,因此,只能将结果设置为-1。 27 | while len(t) > 0: 28 | ans[t[-1]] = -1 29 | t.pop() 30 | 31 | return ans 32 | 33 | 34 | # 测试代码 35 | solution = Solution() 36 | assert [1,-1] == solution.findRightSmall([5,4]) 37 | assert [5, 5, 5, 4, 5, -1, -1] == solution.findRightSmall([1, 2, 4, 9, 4, 0, 5]) 38 | -------------------------------------------------------------------------------- /01.Stack/Example04.java: -------------------------------------------------------------------------------- 1 | 2 | import java.util.Arrays; 3 | import java.util.Stack; 4 | 5 | class Solution { 6 | public static int[] findSmallSeq(int[] nums, int k) { 7 | int[] ans = new int[k]; 8 | Stack s = new Stack<>(); 9 | 10 | // 这里生成单调栈 11 | for (int i = 0; i < nums.length; i++) { 12 | final int x = nums[i]; 13 | final int left = nums.length - i; 14 | // 注意我们想要提取出k个数,所以注意控制扔掉的数的个数 15 | while (!s.empty() && (s.size() + left > k) && s.peek() > x) { 16 | s.pop(); 17 | } 18 | s.push(x); 19 | } 20 | 21 | // 如果递增栈里面的数太多,那么我们只需要取出前k个就可以了。 22 | // 多余的栈中的元素需要扔掉。 23 | while (s.size() > k) { 24 | s.pop(); 25 | } 26 | 27 | // 把k个元素取出来,注意这里取的顺序! 28 | for (int i = k - 1; i >= 0; i--) { 29 | ans[i] = s.peek(); 30 | s.pop(); 31 | } 32 | 33 | return ans; 34 | } 35 | } 36 | 37 | class Example04 { 38 | public static void main(String[] args) { 39 | assert(Arrays.equals(new int[]{1,2,3}, Solution.findSmallSeq(new int[]{9,2,4,5,1,2,6,3,100,4}, 3))); 40 | assert(Arrays.equals(new int[]{1,2}, Solution.findSmallSeq(new int[]{9,2,4,5,1,2,6,3,100,4}, 2))); 41 | assert(Arrays.equals(new int[]{1}, Solution.findSmallSeq(new int[]{9,2,4,5,1,2,6,3,100,4}, 1))); 42 | assert(Arrays.equals(new int[]{1}, Solution.findSmallSeq(new int[]{1,1,1,1,1}, 1))); 43 | } 44 | } -------------------------------------------------------------------------------- /01.Stack/Example04.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | class Solution: 4 | def findSmallSeq(self, nums, k): 5 | if not nums or len(nums) == 0 or k <= 0: 6 | return [] 7 | 8 | ans = [0] * k 9 | s = [] 10 | 11 | # 这里生成单调栈 12 | for i in range(0, len(nums)): 13 | x = nums[i] 14 | left = len(nums) - i 15 | # 注意我们想要提取出k个数,所以注意控制扔掉的数的个数 16 | while len(s) > 0 and (len(s) + left) > k and s[-1] > x: 17 | s.pop() 18 | s.append(x) 19 | 20 | # 如果递增栈里面的数太多,那么我们只需要取出前k个就可以了。 21 | # 多余的栈中的元素需要扔掉。 22 | while len(s) > k: 23 | s.pop() 24 | 25 | # 把k个元素取出来,注意这里取的顺序! 26 | for i in range(k-1, -1, -1): 27 | ans[i] = s[-1] 28 | s.pop() 29 | 30 | return ans 31 | 32 | # 测试代码 33 | solution = Solution() 34 | assert [1,2,3] == solution.findSmallSeq([9,2,4,5,1,2,6,3,100,4], 3) 35 | assert [1,2] == solution.findSmallSeq([9,2,4,5,1,2,6,3,100,4], 2) 36 | assert [1] == solution.findSmallSeq([9,2,4,5,1,2,6,3,100,4], 1) -------------------------------------------------------------------------------- /01.Stack/Fish.cpp: -------------------------------------------------------------------------------- 1 | // 测试链接:https://app.codility.com/programmers/lessons/7-stacks_and_queues/fish/start/ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | using namespace std; 20 | 21 | int solution(vector &A, vector &B) { 22 | // write your code in C++14 (g++ 6.2.0) 23 | const int N = A.size(); 24 | if (N <= 1) 25 | return N; 26 | constexpr int L = 0; 27 | constexpr int R = 1; 28 | 29 | stack t; 30 | for (int i = 0; i < N; i++) { 31 | const int D = B[i]; 32 | const int S = A[i]; 33 | 34 | bool has_eat = false; 35 | while (!t.empty() && B[t.top()] == R && D == L) { 36 | // 如果栈顶的鱼比较大,那么把新来的吃掉 37 | if (A[t.top()] > S) { 38 | has_eat = true; 39 | break; 40 | } 41 | t.pop(); 42 | } 43 | if (has_eat) 44 | continue; 45 | 46 | t.push(i); 47 | } 48 | 49 | return t.size(); 50 | } -------------------------------------------------------------------------------- /01.Stack/Fish.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 测试链接: https://app.codility.com/programmers/lessons/7-stacks_and_queues/fish/start/ 3 | # you can write to stdout for debugging purposes, e.g. 4 | # print("this is a debug message") 5 | 6 | def solution(fishSize, fishDirection): 7 | # write your code in Python 3.6 8 | fishNumber = len(fishSize) 9 | if fishNumber <= 1: 10 | return fishNumber 11 | 12 | left = 0 13 | right = 1 14 | 15 | t = [] 16 | 17 | for i in range(0, fishNumber): 18 | # 当前鱼的情况:1,游动的方向;2,大小 19 | curFishDirection = fishDirection[i] 20 | curFishSize = fishSize[i] 21 | 22 | # 当前的鱼是否被栈中的鱼吃掉了 23 | hasEat = False 24 | 25 | # 如果栈中还有鱼,并且栈中鱼向右,当前的鱼向左游,那么就会有相遇的可能性 26 | while len(t) > 0 and fishDirection[t[-1]] == right and curFishDirection == left: 27 | # 如果栈顶的鱼比较大,那么把新来的吃掉 28 | if fishSize[t[-1]] > curFishSize: 29 | hasEat = True 30 | break 31 | 32 | # 如果栈中的鱼较小,那么会把栈中的鱼吃掉,栈中的鱼被消除,所以需要弹栈。 33 | t.pop() 34 | 35 | # 如果新来的鱼,没有被吃掉,那么压入栈中。 36 | if not hasEat: 37 | t.append(i) 38 | 39 | return len(t) -------------------------------------------------------------------------------- /01.Stack/右边第一个比我大.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 题目:给定一个数组,要找到这个数组里面每个元素右边比我大的元素的位置 3 | * - 注意:是右边第一个比我大的,如果有多个的话 4 | * - 如果没有,那么用-1表示。 5 | * 返回:一个数组,表示右边比我大的数的下标位置 6 | * 7 | * 输入:[5, 6] 8 | * 输出:[1, -1] 9 | * 解释:A[0] = 5,右边比我大的是A[1] = 6, 所以记录为 = 1 10 | * A[1] = 6, 右边比我大的元素没有,所以记录为 = -1 11 | * 所以返回值是[1, -1] 12 | */ 13 | 14 | class Solution { 15 | 16 | vector findRightLarge(vector &A) { 17 | if (A.empty()) { 18 | return {}; 19 | } 20 | // 结果数组 21 | vector ans(A.size()); 22 | 23 | // 注意,栈中的元素记录的是下标 24 | stack t; 25 | 26 | for (size_t i = 0; i < A.size(); i++) { 27 | const int x = A[i]; 28 | // 每个元素都向左遍历栈中的元素完成消除动作 29 | while (!t.empty() && A[t.top()] < x) { 30 | // 消除的时候,记录一下被谁消除了 31 | ans[t.top()] = i; 32 | // 消除时候,值更大的需要从栈中消失 33 | t.pop(); 34 | } 35 | // 剩下的入栈 36 | t.push(i); 37 | } 38 | // 栈中剩下的元素,由于没有人能消除他们,因此,只能将结果设置为-1。 39 | while (!t.empty()) { 40 | ans[t.top()] = -1; 41 | t.pop(); 42 | } 43 | 44 | return ans; 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /01.Stack/右边第一个比我大.py: -------------------------------------------------------------------------------- 1 | class RightLarge: 2 | def findRightLarge(self, A): 3 | if not A or len(A) == 0: 4 | return [] 5 | 6 | # 结果数组 7 | ans =[0] * len(A) 8 | 9 | # 注意,栈中的元素记录的是下标 10 | t = [] 11 | 12 | for i in range(0, len(A)): 13 | x = A[i] 14 | # 每个元素都向左遍历栈中的元素完成消除动作 15 | while len(t) > 0 and A[t[-1]] < x: 16 | # 消除的时候,记录一下被谁消除了 17 | ans[t[-1]] = i 18 | # 消除时候,值更大的需要从栈中消失 19 | t.pop() 20 | 21 | # 剩下的入栈 22 | t.append(i) 23 | 24 | # 栈中剩下的元素,由于没有人能消除他们,因此,只能将结果设置为-1。 25 | while len(t) > 0: 26 | ans[t[-1]] = -1 27 | t.pop() 28 | 29 | return ans 30 | -------------------------------------------------------------------------------- /01.Stack/左边第一个比我大.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * 题目:给定一个数组,要找到这个数组里面每个元素左边比我大的元素的位置 4 | * - 注意:是左边第一个比我大的,如果有多个的话 5 | * - 如果没有,那么用-1表示。 6 | * 7 | * 返回:一个数组,表示左边比我大的数的下标位置 8 | * 9 | * 输入:[5, 6] 10 | * 输出:[-1, -1] 11 | * 解释:A[0] = 5,左边比我大的元素没有, 所以记录为 = -1 12 | * A[1] = 6, 左边比我大的元素为没有,所以记录为 = -1 13 | * 所以返回值是[-1, -1] 14 | */ 15 | 16 | class Solution { 17 | public: 18 | vector findLeftLarge(vector& A) { 19 | if (A.empty()) { 20 | return {}; 21 | } 22 | const int N = A.size(); 23 | 24 | // 结果数组 25 | vector ans(N); 26 | 27 | // 注意,栈中的元素记录的是下标 28 | stack t; 29 | 30 | // 注意这里的遍历方向发生了变化,因为我们是要找到左边比我小的元素的位置 31 | for (int i = N - 1; i >= 0; i--) { 32 | const int x = A[i]; 33 | // 每个元素都遍历栈中的元素完成消除动作 34 | // 这里是递减栈 35 | // 如果发现进来的元素x与栈中元素相比 36 | // 如果大于栈中的元素,那么要把栈中的元素弹出去 37 | while (!t.empty() && A[t.top()] < x) { 38 | // 消除的时候,记录一下被谁消除了 39 | ans[t.top()] = i; 40 | // 消除时候,值更大的需要从栈中消失 41 | t.pop(); 42 | } 43 | // 剩下的入栈 44 | t.push(i); 45 | } 46 | // 栈中剩下的元素,由于没有人能消除他们,因此,只能将结果设置为-1。 47 | while (!t.empty()) { 48 | ans[t.top()] = -1; 49 | t.pop(); 50 | } 51 | 52 | return ans; 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /01.Stack/左边第一个比我大.py: -------------------------------------------------------------------------------- 1 | 2 | class LeftLarge: 3 | def findLeftLarge(self, A): 4 | if not A or len(A) == 0: 5 | return [] 6 | 7 | # 结果数组 8 | ans =[0] * len(A) 9 | 10 | # 注意,栈中的元素记录的是下标 11 | t = [] 12 | 13 | for i in range(len(A)-1, -1, -1): 14 | x = A[i] 15 | # 每个元素都向左遍历栈中的元素完成消除动作 16 | while len(t) > 0 and A[t[-1]] < x: 17 | # 消除的时候,记录一下被谁消除了 18 | ans[t[-1]] = i 19 | # 消除时候,值更大的需要从栈中消失 20 | t.pop() 21 | 22 | # 剩下的入栈 23 | t.append(i) 24 | 25 | # 栈中剩下的元素,由于没有人能消除他们,因此,只能将结果设置为-1。 26 | while len(t) > 0: 27 | ans[t[-1]] = -1 28 | t.pop() 29 | 30 | return ans 31 | -------------------------------------------------------------------------------- /01.Stack/左边第一个比我小.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * 题目:给定一个数组,要找到这个数组里面每个元素左边比我小的元素的位置 4 | * - 注意:是左边第一个比我小的,如果有多个的话 5 | * - 如果没有,那么用-1表示。 6 | * 7 | * 返回:一个数组,表示左边比我小的数的下标位置 8 | * 9 | * 输入:[5, 6] 10 | * 输出:[-1, 0] 11 | * 解释:A[0] = 5,左边比我小的元素没有, 所以记录为 = -1 12 | * A[1] = 6, 左边比我小的元素为A[0] = 5,所以记录为 = 0 13 | * 所以返回值是[-1, 0] 14 | */ 15 | 16 | class LeftSmall { 17 | // 当我们要找左边比我小的元素的时候,需要用递增栈 18 | public: 19 | static vector findLeftSmall(vector& A) { 20 | if (A.empty()) { 21 | return {}; 22 | } 23 | const int N = A.size(); 24 | 25 | // 结果数组 26 | vector ans(N); 27 | 28 | // 注意,栈中的元素记录的是下标 29 | stack t; 30 | 31 | // 注意这里的遍历方向发生了变化,因为我们是要找到左边比我小的元素的位置 32 | for (int i = N - 1; i >= 0; i--) { 33 | const int x = A[i]; 34 | // 每个元素都遍历栈中的元素完成消除动作 35 | // 这里是递减栈 36 | // 如果发现进来的元素x与栈中元素相比 37 | // 如果大于栈中的元素,那么要把栈中的元素弹出去 38 | while (!t.empty() && A[t.top()] > x) { 39 | // 消除的时候,记录一下被谁消除了 40 | ans[t.top()] = i; 41 | // 消除时候,值更大的需要从栈中消失 42 | t.pop(); 43 | } 44 | // 剩下的入栈 45 | t.push(i); 46 | } 47 | // 栈中剩下的元素,由于没有人能消除他们,因此,只能将结果设置为-1。 48 | while (!t.empty()) { 49 | ans[t.top()] = -1; 50 | t.pop(); 51 | } 52 | 53 | return ans; 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /01.Stack/左边第一个比我小.py: -------------------------------------------------------------------------------- 1 | 2 | class LeftSmall: 3 | def findLeftSmall(self, A): 4 | if not A or len(A) == 0: 5 | return [] 6 | 7 | # 结果数组 8 | ans =[0] * len(A) 9 | 10 | # 注意,栈中的元素记录的是下标 11 | t = [] 12 | 13 | for i in range(len(A)-1,-1,-1): 14 | x = A[i] 15 | # 每个元素都向左遍历栈中的元素完成消除动作 16 | while len(t) > 0 and A[t[-1]] > x: 17 | # 消除的时候,记录一下被谁消除了 18 | ans[t[-1]] = i 19 | # 消除时候,值更大的需要从栈中消失 20 | t.pop() 21 | 22 | # 剩下的入栈 23 | t.append(i) 24 | 25 | # 栈中剩下的元素,由于没有人能消除他们,因此,只能将结果设置为-1。 26 | while len(t) > 0: 27 | ans[t[-1]] = -1 28 | t.pop() 29 | 30 | return ans 31 | -------------------------------------------------------------------------------- /02.Queue/01.2.TreeLevelOrder.cpp: -------------------------------------------------------------------------------- 1 | // 本题测试平台链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/ 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | vector> levelOrder(TreeNode* root) { 15 | vector> ans; 16 | 17 | // 生成当前层 18 | vector cur; 19 | // 注意加入的条件,不能把空指针放进去 20 | if (root) { 21 | cur.push_back(root); 22 | } 23 | 24 | vector nextLevel; 25 | 26 | while (!cur.empty()) { 27 | // 一定要记得把下一层清空 28 | nextLevel.clear(); 29 | 30 | // 在结果层中新生成一层,ans.back()专门用来存放结果 31 | ans.emplace_back(); 32 | 33 | for (auto c: cur) { 34 | // 存放当前层的结果 35 | ans.back().push_back(c->val); 36 | 37 | // 专门用来存放下一层结果 38 | if (c->left) { 39 | nextLevel.push_back(c->left); 40 | } 41 | if (c->right) { 42 | nextLevel.push_back(c->right); 43 | } 44 | } 45 | 46 | // c++里面更迭的技巧 47 | // 把下一层更迭为当前层。 48 | cur.swap(nextLevel); 49 | } 50 | 51 | return ans; 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /02.Queue/01.2.TreeLevelOrder.py: -------------------------------------------------------------------------------- 1 | # 本题的测试平台链接: 2 | # https://leetcode-cn.com/problems/binary-tree-level-order-traversal/ 3 | 4 | # Definition for a binary tree node. 5 | # class TreeNode(object): 6 | # def __init__(self, x): 7 | # self.val = x 8 | # self.left = None 9 | # self.right = None 10 | 11 | class Solution(object): 12 | def levelOrder(self, root): 13 | """ 14 | :type root: TreeNode 15 | :rtype: List[List[int]] 16 | """ 17 | # 存放每一层遍历的结果 18 | ans = [] 19 | 20 | # 记录当前层,注意不要把空的root放进去 21 | cur = [] 22 | if root: 23 | cur.append(root) 24 | 25 | while len(cur): 26 | # nextLevel用来存放下一层的结点 27 | nextLevel = [] 28 | 29 | # curResult用来存放当前层的值 30 | curResult = [] 31 | 32 | for c in cur: 33 | # 把当前层的值放到curResult里面 34 | curResult.append(c.val) 35 | 36 | # 生成下一层 37 | if c.left: 38 | nextLevel.append(c.left) 39 | if c.right: 40 | nextLevel.append(c.right) 41 | 42 | # 指向下一层 43 | cur = nextLevel 44 | 45 | # 把当前层放到结果中 46 | ans.append([x for x in curResult]) 47 | 48 | # 返回结果 49 | return ans 50 | -------------------------------------------------------------------------------- /02.Queue/01.TreeLevelOrder.cpp: -------------------------------------------------------------------------------- 1 | // 本题测试平台链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/ 2 | /** 3 | * Definition for a binary tree node. 4 | * struct TreeNode { 5 | * int val; 6 | * TreeNode *left; 7 | * TreeNode *right; 8 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 9 | * }; 10 | */ 11 | 12 | class Solution { 13 | public: 14 | vector> levelOrder(TreeNode *root) { 15 | queue Q; 16 | // 注意,入队的时候都不能为空 17 | if (root) { 18 | Q.push(root); 19 | } 20 | 21 | vector> ans; 22 | 23 | while (!Q.empty()) { 24 | // 生成新的一层 25 | ans.emplace_back(); 26 | // 拿到当前层的结点个数 27 | int qSize = Q.size(); 28 | 29 | // 依次取出当前层的结点 30 | while (qSize--) { 31 | // 照顺序取出当前层的结点 32 | auto cur = Q.front(); 33 | Q.pop(); 34 | // 把结点值放到当前层 35 | ans.back().push_back(cur->val); 36 | 37 | // 取出下一层,并且放到队列中。 38 | if (cur->left) { 39 | Q.push(cur->left); 40 | } 41 | if (cur->right) { 42 | Q.push(cur->right); 43 | } 44 | } 45 | } 46 | 47 | // 返回结果 48 | return ans; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /02.Queue/01.TreeLevelOrder.py: -------------------------------------------------------------------------------- 1 | # 本题的测试平台链接: 2 | # https://leetcode-cn.com/problems/binary-tree-level-order-traversal/ 3 | # 4 | # Definition for a binary tree node. 5 | # class TreeNode(object): 6 | # def __init__(self, x): 7 | # self.val = x 8 | # self.left = None 9 | # self.right = None 10 | import Queue as queue 11 | class Solution(object): 12 | def levelOrder(self, root): 13 | """ 14 | :type root: TreeNode 15 | :rtype: List[List[int]] 16 | """ 17 | # 生成FIFO队列 18 | Q = queue.Queue() 19 | 20 | # 如果结点不为空,那么放到队列中 21 | if root: 22 | Q.put(root) 23 | 24 | # 需要返回的结果 25 | ans = [] 26 | 27 | # 依次处理,直到遍历完所有的元素 28 | while not Q.empty(): 29 | # 拿到当前层结点的个数 30 | qSize = Q.qsize() 31 | # 存放当前层遍历的结果 32 | curLevel = [] 33 | 34 | # 依次取出当前层的结点 35 | for i in range(qSize): 36 | # 把当前层的结点放到curLevel里面。 37 | cur = Q.get() 38 | curLevel.append(cur.val) 39 | 40 | # 按照顺序取出下一层 41 | if cur.left: 42 | Q.put(cur.left) 43 | if cur.right: 44 | Q.put(cur.right) 45 | # 把当前层添加到结果里面 46 | ans.append([x for x in curLevel]) 47 | 48 | # 返回最终的结果 49 | return ans 50 | -------------------------------------------------------------------------------- /03.HeapAndPriorityQueue/347.前-k-个高频元素.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=347 lang=python 3 | # 4 | # [347] 前 K 个高频元素 5 | # 6 | # https://leetcode-cn.com/problems/top-k-frequent-elements/description/ 7 | # 8 | # algorithms 9 | # Medium (61.87%) 10 | # Likes: 653 11 | # Dislikes: 0 12 | # Total Accepted: 136.4K 13 | # Total Submissions: 220.1K 14 | # Testcase Example: '[1,1,1,2,2,3]\n2' 15 | # 16 | # 给定一个非空的整数数组,返回其中出现频率前 k 高的元素。 17 | # 18 | # 19 | # 20 | # 示例 1: 21 | # 22 | # 输入: nums = [1,1,1,2,2,3], k = 2 23 | # 输出: [1,2] 24 | # 25 | # 26 | # 示例 2: 27 | # 28 | # 输入: nums = [1], k = 1 29 | # 输出: [1] 30 | # 31 | # 32 | # 33 | # 提示: 34 | # 35 | # 36 | # 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。 37 | # 你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。 38 | # 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。 39 | # 你可以按任意顺序返回答案。 40 | # 41 | # 42 | # 43 | 44 | # @lc code=start 45 | import heapq 46 | class Solution(object): 47 | def topKFrequent(self, A, k): 48 | count = collections.Counter(A) 49 | # 注意这里是小堆 50 | # python原本是大堆,这里取负变成小堆 51 | heap = [(-freq, word) for word, freq in count.items()] 52 | heapq.heapify(heap) 53 | return [heapq.heappop(heap)[1] for _ in xrange(k)] 54 | 55 | # @lc code=end 56 | 57 | -------------------------------------------------------------------------------- /03.HeapAndPriorityQueue/README.md: -------------------------------------------------------------------------------- 1 | # 堆与优先级队列 2 | 3 | - [根据字符出现频率排序](https://leetcode-cn.com/problems/sort-characters-by-frequency/) [代码](.) 4 | - [前 K 个高频元素](https://leetcode-cn.com/problems/top-k-frequent-elements/) [代码](./) 5 | - [前K个高频单词](https://leetcode-cn.com/problems/top-k-frequent-words/) [代码](./) 6 | - [最接近原点的 K 个点](https://leetcode-cn.com/problems/k-closest-points-to-origin/) [代码](./) 7 | - [重构字符串](https://leetcode-cn.com/problems/reorganize-string/) [代码](./) 8 | - [数组中的第K个最大元素](https://leetcode-cn.com/problems/kth-largest-element-in-an-array/) [代码](./) 9 | - [数据流中的第 K 大元素](https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/) [代码](./) 10 | - [合并K个升序链表](https://leetcode-cn.com/problems/merge-k-sorted-lists/) [代码](./) 11 | 12 | -------------------------------------------------------------------------------- /03.HeapAndPriorityQueue/heap.cpp: -------------------------------------------------------------------------------- 1 | class Heap { 2 | public: 3 | vector a; 4 | int n = 0; 5 | 6 | void sink(int i) { 7 | int j = 0; 8 | int t = a[i]; 9 | while ((j = (i << 1) + 1) < n) { 10 | if (j < n - 1 && a[j] < a[j + 1]) { 11 | j++; 12 | } 13 | if (a[j] > t) { 14 | a[i] = a[j]; 15 | i = j; 16 | } else { 17 | break; 18 | } 19 | } 20 | a[i] = t; 21 | } 22 | 23 | void swim(int i) { 24 | int par = 0; 25 | int t = a[i]; 26 | while (i > 0) { 27 | par = (i - 1) >> 1; 28 | if (a[par] < t) { 29 | a[i] = a[par]; 30 | i = par; 31 | } else { 32 | break; 33 | } 34 | } 35 | a[i] = t; 36 | } 37 | 38 | void push(int x) { 39 | a[n++] = x; 40 | swim(n - 1); 41 | } 42 | 43 | int pop() { 44 | int ret = a[0]; 45 | a[0] = a[--n]; 46 | sink(0); 47 | return ret; 48 | } 49 | 50 | int size() const { return n; } 51 | }; 52 | 53 | -------------------------------------------------------------------------------- /03.HeapAndPriorityQueue/heap.py: -------------------------------------------------------------------------------- 1 | class Heap(object): 2 | a = [] 3 | n = 0 4 | 5 | def _sink(self, i): 6 | t = self.a[i] 7 | while i + i + 1 < self.n: 8 | j = i + i + 1 9 | if j < self.n - 1 and self.a[j] < self.a[j+1]: 10 | j += 1 11 | if self.a[j] > t: 12 | self.a[i] = self.a[j] 13 | i = j 14 | else: 15 | break 16 | self.a[i] = t 17 | 18 | def _swim(self, i): 19 | t = self.a[i] 20 | while i > 0: 21 | par = (i-1) / 2 22 | if self.a[par] < t: 23 | self.a[i] = self.a[par] 24 | i = par 25 | else: 26 | break 27 | self.a[i] = t 28 | 29 | def push(self, x): 30 | self.a.append(x) 31 | self._swim(self.n) 32 | self.n += 1 33 | 34 | def pop(self): 35 | ret = self.a[0] 36 | self.a[0] = self.a[self.n-1] 37 | self.a.pop() 38 | self.n -= 1 39 | self._sink(0) 40 | return ret 41 | 42 | def size(self): 43 | return self.n 44 | -------------------------------------------------------------------------------- /03.HeapAndPriorityQueue/剑指Offer40.最小的k个数.cpp: -------------------------------------------------------------------------------- 1 | // 测试平台: https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/ 2 | class Solution { 3 | public: 4 | vector getLeastNumbers(vector& arr, int k) { 5 | if (k <= 0 || arr.empty()) { 6 | return {}; 7 | } 8 | 9 | if (arr.size() <= k) { 10 | return arr; 11 | } 12 | 13 | // c++默认是大堆 14 | priority_queue Q; 15 | 16 | for (auto x: arr) { 17 | // 所有元素都要入堆 18 | Q.push(x); 19 | // 如果超出k个元素 20 | // 那么将较大的元素扔掉 21 | while (Q.size() > k) { 22 | Q.pop(); 23 | } 24 | } 25 | 26 | // Q中已经保留了最小的k个数,这里生成返回值 27 | vector ans; 28 | while (Q.size() > 0) { 29 | ans.push_back(Q.top()); 30 | Q.pop(); 31 | } 32 | 33 | return ans; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /03.HeapAndPriorityQueue/剑指Offer40.最小的k个数.java: -------------------------------------------------------------------------------- 1 | // 测试平台链接:https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/ 2 | class Solution { 3 | public int[] getLeastNumbers(int[] arr, int k) { 4 | if (k <= 0 || arr == null || arr.length == 0) { 5 | return new int[0]; 6 | } 7 | 8 | Queue Q = new PriorityQueue<>((v1, v2) -> v2 - v1); 9 | for (int x: arr) { 10 | Q.offer(x); 11 | while (Q.size() > k) { 12 | Q.poll(); 13 | } 14 | } 15 | 16 | int[] ans = new int[k]; 17 | int i = 0; 18 | for (int x: Q) { 19 | ans[i++] = x; 20 | } 21 | 22 | return ans; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /03.HeapAndPriorityQueue/剑指Offer40.最小的k个数.py: -------------------------------------------------------------------------------- 1 | import Queue 2 | from Queue import PriorityQueue 3 | 4 | class Solution(object): 5 | def getLeastNumbers(self, arr, k): 6 | """ 7 | :type arr: List[int] 8 | :type k: int 9 | :rtype: List[int] 10 | """ 11 | 12 | if k <= 0 or (not arr) or len(arr) == 0: 13 | return [] 14 | 15 | Q = PriorityQueue() 16 | for x in arr: 17 | Q.put(-x) 18 | while Q.qsize() > k: 19 | Q.get() 20 | 21 | ans = [] 22 | while not Q.empty(): 23 | ans.append(-Q.get()) 24 | return ans 25 | -------------------------------------------------------------------------------- /05.LinkedList/203.移除链表元素.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=203 lang=cpp 3 | * 4 | * [203] 移除链表元素 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * struct ListNode { 11 | * int val; 12 | * ListNode *next; 13 | * ListNode(int x) : val(x), next(NULL) {} 14 | * }; 15 | */ 16 | class Solution { 17 | public: 18 | ListNode* removeElements(ListNode* head, int val) { 19 | ListNode dummy, *tail = &dummy; 20 | 21 | auto p = head; 22 | 23 | while (p) { 24 | auto back = p->next; 25 | 26 | if (p->val != val) { 27 | tail->next = p; 28 | tail = p; 29 | } 30 | 31 | p = back; 32 | } 33 | tail->next = nullptr; 34 | 35 | return dummy.next; 36 | } 37 | }; 38 | // @lc code=end 39 | -------------------------------------------------------------------------------- /05.LinkedList/203.移除链表元素.java: -------------------------------------------------------------------------------- 1 | import MyLinkedList.ListNode; 2 | 3 | /* 4 | * @lc app=leetcode.cn id=203 lang=java 5 | * 6 | * [203] 移除链表元素 7 | * 8 | * https://leetcode-cn.com/problems/remove-linked-list-elements/description/ 9 | * 10 | * algorithms 11 | * Easy (46.96%) 12 | * Likes: 539 13 | * Dislikes: 0 14 | * Total Accepted: 134.8K 15 | * Total Submissions: 286.5K 16 | * Testcase Example: '[1,2,6,3,4,5,6]\n6' 17 | * 18 | * 删除链表中等于给定值 val 的所有节点。 19 | * 20 | * 示例: 21 | * 22 | * 输入: 1->2->6->3->4->5->6, val = 6 23 | * 输出: 1->2->3->4->5 24 | * 25 | * 26 | */ 27 | 28 | // @lc code=start 29 | /** 30 | * Definition for singly-linked list. public class ListNode { int val; ListNode 31 | * next; ListNode() {} ListNode(int val) { this.val = val; } ListNode(int val, 32 | * ListNode next) { this.val = val; this.next = next; } } 33 | */ 34 | class Solution { 35 | public ListNode removeElements(ListNode head, int val) { 36 | ListNode dummy = new ListNode(); 37 | ListNode tail = dummy; 38 | ListNode p = head; 39 | 40 | while (p != null) { 41 | ListNode back = p.next; 42 | 43 | if (p.val != val) { 44 | tail.next = p; 45 | tail = p; 46 | } 47 | 48 | p = back; 49 | } 50 | 51 | tail.next = null; 52 | return dummy.next; 53 | } 54 | } 55 | // @lc code=end 56 | -------------------------------------------------------------------------------- /05.LinkedList/203.移除链表元素.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=203 lang=python 3 | # 4 | # [203] 移除链表元素 5 | # 6 | # https://leetcode-cn.com/problems/remove-linked-list-elements/description/ 7 | # 8 | # algorithms 9 | # Easy (46.96%) 10 | # Likes: 539 11 | # Dislikes: 0 12 | # Total Accepted: 134.8K 13 | # Total Submissions: 286.5K 14 | # Testcase Example: '[1,2,6,3,4,5,6]\n6' 15 | # 16 | # 删除链表中等于给定值 val 的所有节点。 17 | # 18 | # 示例: 19 | # 20 | # 输入: 1->2->6->3->4->5->6, val = 6 21 | # 输出: 1->2->3->4->5 22 | # 23 | # 24 | # 25 | 26 | # @lc code=start 27 | # Definition for singly-linked list. 28 | # class ListNode(object): 29 | # def __init__(self, val=0, next=None): 30 | # self.val = val 31 | # self.next = next 32 | class Solution(object): 33 | def removeElements(self, head, val): 34 | dummy = ListNode() 35 | tail = dummy 36 | p = head 37 | 38 | while p: 39 | back = p.next 40 | 41 | if p.val != val: 42 | tail.next = p 43 | tail = p 44 | 45 | p = back 46 | tail.next = None 47 | 48 | return dummy.next 49 | # @lc code=end 50 | 51 | -------------------------------------------------------------------------------- /05.LinkedList/206.反转链表.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=206 lang=cpp 3 | * 4 | * [206] 反转链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * struct ListNode { 11 | * int val; 12 | * ListNode *next; 13 | * ListNode(int x) : val(x), next(NULL) {} 14 | * }; 15 | */ 16 | class Solution { 17 | public: 18 | ListNode* reverseList(ListNode* head) { 19 | ListNode* d = nullptr; 20 | auto p = head; 21 | while (p) { 22 | auto back = p->next; 23 | p->next = d; 24 | d = p; 25 | p = back; 26 | } 27 | return d; 28 | } 29 | }; 30 | // @lc code=end 31 | -------------------------------------------------------------------------------- /05.LinkedList/206.反转链表.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=206 lang=java 3 | * 4 | * [206] 反转链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * public class ListNode { 11 | * int val; 12 | * ListNode next; 13 | * ListNode(int x) { val = x; } 14 | * } 15 | */ 16 | class Solution { 17 | public ListNode reverseList(ListNode head) { 18 | ListNode dummy = new ListNode(); 19 | while (head != null) { 20 | ListNode tmp = head.next; 21 | 22 | head.next = dummy.next; 23 | dummy.next = head; 24 | 25 | head = tmp; 26 | } 27 | return dummy.next; 28 | } 29 | } 30 | // @lc code=end 31 | 32 | -------------------------------------------------------------------------------- /05.LinkedList/206.反转链表.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=206 lang=python 3 | # 4 | # [206] 反转链表 5 | # 6 | # https://leetcode-cn.com/problems/reverse-linked-list/description/ 7 | # 8 | # algorithms 9 | # Easy (71.37%) 10 | # Likes: 1542 11 | # Dislikes: 0 12 | # Total Accepted: 445.9K 13 | # Total Submissions: 623.8K 14 | # Testcase Example: '[1,2,3,4,5]' 15 | # 16 | # 反转一个单链表。 17 | # 18 | # 示例: 19 | # 20 | # 输入: 1->2->3->4->5->NULL 21 | # 输出: 5->4->3->2->1->NULL 22 | # 23 | # 进阶: 24 | # 你可以迭代或递归地反转链表。你能否用两种方法解决这道题? 25 | # 26 | # 27 | 28 | # @lc code=start 29 | # Definition for singly-linked list. 30 | # class ListNode(object): 31 | # def __init__(self, val=0, next=None): 32 | # self.val = val 33 | # self.next = next 34 | class Solution(object): 35 | def reverseList(self, head): 36 | """ 37 | :type head: ListNode 38 | :rtype: ListNode 39 | """ 40 | 41 | dummy = ListNode() 42 | 43 | p = head 44 | 45 | while p: 46 | back = p.next 47 | 48 | p.next = dummy.next 49 | dummy.next = p 50 | 51 | p = back 52 | 53 | return dummy.next 54 | # @lc code=end 55 | 56 | -------------------------------------------------------------------------------- /05.LinkedList/83.删除排序链表中的重复元素.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=83 lang=cpp 3 | * 4 | * [83] 删除排序链表中的重复元素 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * struct ListNode { 11 | * int val; 12 | * ListNode *next; 13 | * ListNode(int x) : val(x), next(NULL) {} 14 | * }; 15 | */ 16 | class Solution { 17 | public: 18 | ListNode* deleteDuplicates(ListNode* head) { 19 | ListNode dummy, *tail = &dummy; 20 | 21 | auto p = head; 22 | 23 | while (p) { 24 | auto back = p->next; 25 | 26 | if (tail == &dummy || tail->val != p->val) { 27 | tail->next = p; 28 | tail = p; 29 | } 30 | 31 | p = back; 32 | } 33 | 34 | tail->next = nullptr; 35 | return dummy.next; 36 | } 37 | }; 38 | // @lc code=end 39 | -------------------------------------------------------------------------------- /05.LinkedList/83.删除排序链表中的重复元素.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=83 lang=python 3 | # 4 | # [83] 删除排序链表中的重复元素 5 | # 6 | # https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/description/ 7 | # 8 | # algorithms 9 | # Easy (51.98%) 10 | # Likes: 481 11 | # Dislikes: 0 12 | # Total Accepted: 186.7K 13 | # Total Submissions: 358.3K 14 | # Testcase Example: '[1,1,2]' 15 | # 16 | # 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。 17 | # 18 | # 示例 1: 19 | # 20 | # 输入: 1->1->2 21 | # 输出: 1->2 22 | # 23 | # 24 | # 示例 2: 25 | # 26 | # 输入: 1->1->2->3->3 27 | # 输出: 1->2->3 28 | # 29 | # 30 | 31 | # @lc code=start 32 | # Definition for singly-linked list. 33 | # class ListNode(object): 34 | # def __init__(self, val=0, next=None): 35 | # self.val = val 36 | # self.next = next 37 | class Solution(object): 38 | def deleteDuplicates(self, head): 39 | dummy = ListNode() 40 | tail = dummy 41 | 42 | p = head 43 | 44 | while p: 45 | back = p.next 46 | 47 | if tail == dummy or p.val != tail.val: 48 | tail.next = p 49 | tail = p 50 | 51 | p = back 52 | 53 | tail.next = None 54 | return dummy.next 55 | 56 | # @lc code=end 57 | 58 | -------------------------------------------------------------------------------- /05.LinkedList/splitList.2.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | // 如果不使用dummy head 3 | private ListNode findMiddle(ListNode head) { 4 | ListNode pre = head; 5 | ListNode s1 = head; 6 | ListNode s2 = head; 7 | 8 | while (s2 != null && s2.next != null) { 9 | pre = s1; 10 | s1 = s1.next; 11 | s2 = s2.next.next; 12 | } 13 | 14 | return s2 != null ? s1 : pre; 15 | } 16 | 17 | public ListNode[] split(ListNode head) { 18 | ListNode mid = findMiddle(head); 19 | 20 | // 注意,此时mid是可能为空的! 21 | // 所以需要判断是否为空 22 | if (mid == null) { 23 | return new ListNode[] { null, null }; 24 | } 25 | 26 | ListNode front = head; 27 | ListNode back = mid.next; 28 | mid.next = null; 29 | 30 | return new ListNode[] { front, back }; 31 | } 32 | } 33 | // @lc code=end 34 | -------------------------------------------------------------------------------- /05.LinkedList/splitList.3.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | 3 | private ListNode findMiddle(ListNode head) { 4 | ListNode dummy = new ListNode(); 5 | dummy.next = head; 6 | 7 | // 如果都从dummy head出发 8 | // 那么当只有一个结点的时候 9 | // 需要注意split函数的处理 10 | ListNode pre = dummy; 11 | ListNode s1 = dummy; 12 | ListNode s2 = dummy; 13 | 14 | while (s2 != null && s2.next != null) { 15 | pre = s1; 16 | s1 = s1.next; 17 | s2 = s2.next.next; 18 | } 19 | 20 | return s2 != null ? s1 : pre; 21 | } 22 | 23 | private ListNode[] split(ListNode head) { 24 | ListNode mid = findMiddle(head); 25 | ListNode front = head; 26 | // 只有一个结点的进候,back容易指向head 27 | ListNode back = mid.next == head ? null : mid.next; 28 | mid.next = null; 29 | 30 | return new ListNode[] { front, back }; 31 | } 32 | } 33 | // @lc code=end 34 | -------------------------------------------------------------------------------- /05.LinkedList/splitList.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode() : val(0), next(nullptr) {} 7 | * ListNode(int x) : val(x), next(nullptr) {} 8 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 | * }; 10 | */ 11 | class Solution { 12 | ListNode *findMiddleNode(ListNode *head) { 13 | auto s1 = head; 14 | auto s2 = head; 15 | auto pre = s1; 16 | while (s2 && s2->next) { 17 | pre = s1; 18 | s1 = s1->next; 19 | s2 = s2->next->next; 20 | } 21 | return s2 ? s1 : pre; 22 | } 23 | 24 | public: 25 | pair split(ListNode *head) { 26 | // 这里获取了链表的中间结点 27 | auto mid = findMiddleNode(head); 28 | // 拿到链表的中间结点之后,可以得到链表的后半部分的开头 29 | auto back = mid->next; 30 | // 把链表拆分为两半 31 | mid->next = nullptr; 32 | // 返回两个链表的头部 33 | return {head, back}; 34 | } 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /05.LinkedList/splitList.java: -------------------------------------------------------------------------------- 1 | import MyLinkedList.ListNode; 2 | 3 | /** 4 | * Definition for singly-linked list. 5 | * public class ListNode { 6 | * int val; 7 | * ListNode next; 8 | * ListNode() {} 9 | * ListNode(int val) { this.val = val; } 10 | * ListNode(int val, ListNode next) { this.val = val; this.next = next; } 11 | * } 12 | */ 13 | class Solution { 14 | // 这里涉及到考点,找到一个链表的中间点 15 | private ListNode findMiddle(ListNode head) { 16 | ListNode s1 = head; 17 | ListNode s2 = head; 18 | ListNode pre = s1; 19 | while (s2 != null && s2.next != null) { 20 | pre = s1; 21 | s1 = s1.next; 22 | s2 = s2.next.next; 23 | } 24 | return s2 != null ? s1 : pre; 25 | } 26 | 27 | public ListNode[] split(ListNode head) { 28 | // 这里获取了链表的中间结点 29 | ListNode mid = findMiddleNode(head); 30 | // 拿到链表的中间结点之后,可以得到链表的后半部分的开头 31 | ListNode back = mid.next; 32 | // 把链表拆分为两半 33 | mid.next = null; 34 | // 返回两个链表的头部 35 | return new ListNode[] {head, back}; 36 | } 37 | } 38 | // @lc code=end 39 | -------------------------------------------------------------------------------- /05.LinkedList/splitList.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode(object): 3 | # def __init__(self, val=0, next=None): 4 | # self.val = val 5 | # self.next = next 6 | class Solution(object): 7 | def findMiddleNode(self, head): 8 | # 找到链表的中点 9 | s1 = head 10 | s2 = head 11 | pre = s1 12 | while s2 and s2.next: 13 | pre = s1 14 | s1 = s1.next 15 | s2 = s2.next.next 16 | 17 | # 把链表拆成两半 18 | return s1 if s2 else pre 19 | 20 | def split(self, head): 21 | # 这里获取了链表的中间结点 22 | mid = self.findMiddleNode(head) 23 | # 拿到链表的中间结点之后,可以得到链表的后半部分的开头 24 | back = mid.next 25 | # 把链表拆分为两半 26 | mid.next = None 27 | # 返回两个链表的头部 28 | return head, back 29 | -------------------------------------------------------------------------------- /06.Tree/100.相同的树.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * https://www.lintcode.com/problem/same-tree/ 4 | * https://leetcode-cn.com/problems/same-tree/ 5 | * 6 | * [100] 相同的树 7 | */ 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * TreeNode *left; 14 | * TreeNode *right; 15 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 16 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 17 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), 18 | * right(right) {} 19 | * }; 20 | */ 21 | class Solution { 22 | public: 23 | bool isSameTree(TreeNode* p, TreeNode* q) { 24 | if (!p && !q) return true; 25 | if (!p || !q) return false; 26 | return p->val == q->val && isSameTree(p->left, q->left) && 27 | isSameTree(p->right, q->right); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /06.Tree/105.从前序与中序遍历序列构造二叉树.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=105 lang=java 3 | * 4 | * [105] 从前序与中序遍历序列构造二叉树 5 | * 6 | * https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/ 7 | * 8 | * algorithms 9 | * Medium (69.26%) 10 | * Likes: 931 11 | * Dislikes: 0 12 | * Total Accepted: 165.7K 13 | * Total Submissions: 238.9K 14 | * Testcase Example: '[3,9,20,15,7]\n[9,3,15,20,7]' 15 | * 16 | * 根据一棵树的前序遍历与中序遍历构造二叉树。 17 | * 18 | * 注意: 19 | * 你可以假设树中没有重复的元素。 20 | * 21 | * 例如,给出 22 | * 23 | * 前序遍历 preorder = [3,9,20,15,7] 24 | * 中序遍历 inorder = [9,3,15,20,7] 25 | * 26 | * 返回如下的二叉树: 27 | * 28 | * ⁠ 3 29 | * ⁠ / \ 30 | * ⁠ 9 20 31 | * ⁠ / \ 32 | * ⁠ 15 7 33 | * 34 | */ 35 | 36 | // @lc code=start 37 | /** 38 | * Definition for a binary tree node. 39 | * public class TreeNode { 40 | * int val; 41 | * TreeNode left; 42 | * TreeNode right; 43 | * TreeNode() {} 44 | * TreeNode(int val) { this.val = val; } 45 | * TreeNode(int val, TreeNode left, TreeNode right) { 46 | * this.val = val; 47 | * this.left = left; 48 | * this.right = right; 49 | * } 50 | * } 51 | */ 52 | class Solution { 53 | public TreeNode buildTree(int[] preorder, int[] inorder) { 54 | 55 | } 56 | } 57 | // @lc code=end 58 | 59 | -------------------------------------------------------------------------------- /06.Tree/105.从前序与中序遍历序列构造二叉树.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=105 lang=python 3 | # 4 | # [105] 从前序与中序遍历序列构造二叉树 5 | # 6 | # https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/ 7 | # 8 | # algorithms 9 | # Medium (69.26%) 10 | # Likes: 931 11 | # Dislikes: 0 12 | # Total Accepted: 165.7K 13 | # Total Submissions: 238.9K 14 | # Testcase Example: '[3,9,20,15,7]\n[9,3,15,20,7]' 15 | # 16 | # 根据一棵树的前序遍历与中序遍历构造二叉树。 17 | # 18 | # 注意: 19 | # 你可以假设树中没有重复的元素。 20 | # 21 | # 例如,给出 22 | # 23 | # 前序遍历 preorder = [3,9,20,15,7] 24 | # 中序遍历 inorder = [9,3,15,20,7] 25 | # 26 | # 返回如下的二叉树: 27 | # 28 | # ⁠ 3 29 | # ⁠ / \ 30 | # ⁠ 9 20 31 | # ⁠ / \ 32 | # ⁠ 15 7 33 | # 34 | # 35 | 36 | # @lc code=start 37 | # Definition for a binary tree node. 38 | # class TreeNode(object): 39 | # def __init__(self, val=0, left=None, right=None): 40 | # self.val = val 41 | # self.left = left 42 | # self.right = right 43 | class Solution(object): 44 | def buildTree(self, preorder, inorder): 45 | """ 46 | :type preorder: List[int] 47 | :type inorder: List[int] 48 | :rtype: TreeNode 49 | """ 50 | # @lc code=end 51 | 52 | -------------------------------------------------------------------------------- /06.Tree/113.路径总和-ii.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * [113] 路径总和 II 4 | * 5 | * https://www.lintcode.com/problem/path-sum-ii/description 6 | * https://leetcode-cn.com/problems/path-sum-ii/description/ 7 | */ 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * TreeNode *left; 14 | * TreeNode *right; 15 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 16 | * }; 17 | */ 18 | class Solution { 19 | void backtrace(TreeNode *root, int64_t T, int64_t sum, vector &path, vector> &ans) { 20 | if (!root) return; 21 | 22 | path.push_back(root->val); 23 | sum += root->val; 24 | 25 | if (!root->left && !root->right) { 26 | if (sum == T) { 27 | ans.push_back(path); 28 | } 29 | } else { 30 | backtrace(root->left, T, sum, path, ans); 31 | backtrace(root->right, T, sum, path, ans); 32 | } 33 | 34 | path.pop_back(); 35 | } 36 | public: 37 | vector> pathSum(TreeNode* root, int sum) { 38 | if (!root) return {}; 39 | vector path; 40 | vector> ans; 41 | backtrace(root, sum, 0, path, ans); 42 | return ans; 43 | } 44 | }; 45 | 46 | -------------------------------------------------------------------------------- /06.Tree/144.二叉树的前序遍历.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * [144] 二叉树的前序遍历 4 | * 5 | * https://leetcode-cn.com/problems/binary-tree-preorder-traversal/description/ 6 | * https://www.lintcode.com/problem/binary-tree-preorder-traversal/ 7 | * 8 | * algorithms 9 | * Medium (66.89%) 10 | * Likes: 367 11 | * Dislikes: 0 12 | * Total Accepted: 170.7K 13 | * Total Submissions: 255.3K 14 | * Testcase Example: '[1,null,2,3]' 15 | * 16 | * 给定一个二叉树,返回它的 前序 遍历。 17 | * 18 | * 示例: 19 | * 20 | * 输入: [1,null,2,3] 21 | * ⁠ 1 22 | * ⁠ \ 23 | * ⁠ 2 24 | * ⁠ / 25 | * ⁠ 3 26 | * 27 | * 输出: [1,2,3] 28 | * 29 | * 30 | * 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 31 | * 32 | */ 33 | 34 | /** 35 | * Definition for a binary tree node. 36 | * struct TreeNode { 37 | * int val; 38 | * TreeNode *left; 39 | * TreeNode *right; 40 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 41 | * }; 42 | */ 43 | class Solution { 44 | void preOrder(TreeNode *root, vector &ans) { 45 | if (root) { 46 | ans.push_back(root->val); 47 | preOrder(root->left, ans); 48 | preOrder(root->right, ans); 49 | } 50 | } 51 | 52 | public: 53 | vector preorderTraversal(TreeNode *root) { 54 | vector ans; 55 | preOrder(root, ans); 56 | return ans; 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /06.Tree/144.二叉树的前序遍历.java: -------------------------------------------------------------------------------- 1 | import javax.swing.tree.TreeNode; 2 | 3 | /* 4 | * 5 | * [144] 二叉树的前序遍历 6 | * 7 | * https://leetcode-cn.com/problems/binary-tree-preorder-traversal/description/ 8 | * https://www.lintcode.com/problem/binary-tree-preorder-traversal/ 9 | * 10 | * algorithms 11 | * Medium (66.89%) 12 | * Likes: 367 13 | * Dislikes: 0 14 | * Total Accepted: 170.7K 15 | * Total Submissions: 255.3K 16 | * Testcase Example: '[1,null,2,3]' 17 | * 18 | * 给定一个二叉树,返回它的 前序 遍历。 19 | * 20 | * 示例: 21 | * 22 | * 输入: [1,null,2,3] 23 | * ⁠ 1 24 | * ⁠ \ 25 | * ⁠ 2 26 | * ⁠ / 27 | * ⁠ 3 28 | * 29 | * 输出: [1,2,3] 30 | * 31 | * 32 | * 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 33 | * 34 | */ 35 | 36 | import java.util.List; 37 | import java.util.ArrayList; 38 | 39 | /** 40 | * Definition for a binary tree node. public class TreeNode { int val; TreeNode 41 | * left; TreeNode right; TreeNode(int x) { val = x; } } 42 | */ 43 | class Solution { 44 | private void preOrder(TreeNode root, List ans) { 45 | if (root != null) { 46 | ans.add(root.val); 47 | preOrder(root.left, ans); 48 | preOrder(root.right, ans); 49 | } 50 | } 51 | 52 | public List preorderTraversal(TreeNode root) { 53 | List ans = new ArrayList<>(); 54 | preOrder(root, ans); 55 | return ans; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /06.Tree/144.二叉树的前序遍历.py: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # [144] 二叉树的前序遍历 4 | # 5 | # https://leetcode-cn.com/problems/binary-tree-preorder-traversal/description/ 6 | # https://www.lintcode.com/problem/binary-tree-preorder-traversal/ 7 | # 8 | # algorithms 9 | # Medium (66.89%) 10 | # Likes: 367 11 | # Dislikes: 0 12 | # Total Accepted: 170.7K 13 | # Total Submissions: 255.3K 14 | # Testcase Example: '[1,null,2,3]' 15 | # 16 | # 给定一个二叉树,返回它的 前序 遍历。 17 | # 18 | # 示例: 19 | # 20 | # 输入: [1,null,2,3] 21 | # ⁠ 1 22 | # ⁠ \ 23 | # ⁠ 2 24 | # ⁠ / 25 | # ⁠ 3 26 | # 27 | # 输出: [1,2,3] 28 | # 29 | # 30 | # 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 31 | # 32 | # 33 | 34 | # Definition for a binary tree node. 35 | # class TreeNode(object): 36 | # def __init__(self, x): 37 | # self.val = x 38 | # self.left = None 39 | # self.right = None 40 | 41 | class Solution(object): 42 | def preOrder(self, root, ans): 43 | if root: 44 | ans.append(root.val) 45 | self.preOrder(root.left, ans) 46 | self.preOrder(root.right, ans) 47 | 48 | def preorderTraversal(self, root): 49 | """ 50 | :type root: TreeNode 51 | :rtype: List[int] 52 | """ 53 | ans = [] 54 | self.preOrder(root, ans) 55 | return ans 56 | 57 | 58 | -------------------------------------------------------------------------------- /06.Tree/144.二叉树的前序遍历.stack.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * [144] 二叉树的前序遍历 4 | * 5 | * https://leetcode-cn.com/problems/binary-tree-preorder-traversal/description/ 6 | * https://www.lintcode.com/problem/binary-tree-preorder-traversal/ 7 | * 8 | * algorithms 9 | * Medium (66.89%) 10 | * Likes: 367 11 | * Dislikes: 0 12 | * Total Accepted: 170.7K 13 | * Total Submissions: 255.3K 14 | * Testcase Example: '[1,null,2,3]' 15 | * 16 | * 给定一个二叉树,返回它的 前序 遍历。 17 | * 18 | * 示例: 19 | * 20 | * 输入: [1,null,2,3] 21 | * ⁠ 1 22 | * ⁠ \ 23 | * ⁠ 2 24 | * ⁠ / 25 | * ⁠ 3 26 | * 27 | * 输出: [1,2,3] 28 | * 29 | * 30 | * 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 31 | * 32 | */ 33 | 34 | /** 35 | * Definition for a binary tree node. 36 | * struct TreeNode { 37 | * int val; 38 | * TreeNode *left; 39 | * TreeNode *right; 40 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 41 | * }; 42 | */ 43 | class Solution { 44 | public: 45 | vector preorderTraversal(TreeNode* root) { 46 | vector ans; 47 | stack s; 48 | while (root || !s.empty()) { 49 | while (root) { 50 | s.push(root); 51 | ans.push_back(root->val); 52 | root = root->left; 53 | } 54 | root = s.top(); 55 | s.pop(); 56 | root = root->right; 57 | } 58 | return ans; 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /06.Tree/144.二叉树的前序遍历.stack.py: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # [144] 二叉树的前序遍历 4 | # 5 | # https://leetcode-cn.com/problems/binary-tree-preorder-traversal/description/ 6 | # https://www.lintcode.com/problem/binary-tree-preorder-traversal/ 7 | # 8 | # algorithms 9 | # Medium (66.89%) 10 | # Likes: 367 11 | # Dislikes: 0 12 | # Total Accepted: 170.7K 13 | # Total Submissions: 255.3K 14 | # Testcase Example: '[1,null,2,3]' 15 | # 16 | # 给定一个二叉树,返回它的 前序 遍历。 17 | # 18 | # 示例: 19 | # 20 | # 输入: [1,null,2,3] 21 | # ⁠ 1 22 | # ⁠ \ 23 | # ⁠ 2 24 | # ⁠ / 25 | # ⁠ 3 26 | # 27 | # 输出: [1,2,3] 28 | # 29 | # 30 | # 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 31 | # 32 | # 33 | 34 | # Definition for a binary tree node. 35 | # class TreeNode(object): 36 | # def __init__(self, x): 37 | # self.val = x 38 | # self.left = None 39 | # self.right = None 40 | 41 | class Solution(object): 42 | def preorderTraversal(self, root): 43 | """ 44 | :type root: TreeNode 45 | :rtype: List[int] 46 | """ 47 | stack = [] 48 | ans = [] 49 | while root or len(stack) > 0: 50 | while root: 51 | stack.append(root) 52 | ans.append(root.val) 53 | root = root.left 54 | root = stack.pop() 55 | root = root.right 56 | return ans 57 | 58 | -------------------------------------------------------------------------------- /06.Tree/145.二叉树的后序遍历.recursive.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * [145] 二叉树的后序遍历 4 | */ 5 | 6 | /** 7 | * Definition for a binary tree node. 8 | * struct TreeNode { 9 | * int val; 10 | * TreeNode *left; 11 | * TreeNode *right; 12 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 13 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 14 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), 15 | * right(right) {} 16 | * }; 17 | */ 18 | class Solution { 19 | void postOrder(TreeNode *root, vector &ans) { 20 | if (root) { 21 | postOrder(root->left, ans); 22 | postOrder(root->right, ans); 23 | ans.push_back(root->val); 24 | } 25 | } 26 | public: 27 | vector postorderTraversal(TreeNode *root) { 28 | vector ans; 29 | postOrder(root, ans); 30 | return ans; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /06.Tree/145.二叉树的后序遍历.recursive.py: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # [145] 二叉树的后序遍历 4 | # 5 | # https://leetcode-cn.com/problems/binary-tree-postorder-traversal/description/ 6 | # 7 | # algorithms 8 | # Medium (73.92%) 9 | # Likes: 507 10 | # Dislikes: 0 11 | # Total Accepted: 180.4K 12 | # Total Submissions: 244K 13 | # Testcase Example: '[1,null,2,3]' 14 | # 15 | # 给定一个二叉树,返回它的 后序 遍历。 16 | # 17 | # 示例: 18 | # 19 | # 输入: [1,null,2,3] 20 | # ⁠ 1 21 | # ⁠ \ 22 | # ⁠ 2 23 | # ⁠ / 24 | # ⁠ 3 25 | # 26 | # 输出: [3,2,1] 27 | # 28 | # 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 29 | # 30 | # 31 | 32 | # Definition for a binary tree node. 33 | # class TreeNode(object): 34 | # def __init__(self, val=0, left=None, right=None): 35 | # self.val = val 36 | # self.left = left 37 | # self.right = right 38 | class Solution(object): 39 | def postorderTraversal(self, root): 40 | """ 41 | :type root: TreeNode 42 | :rtype: List[int] 43 | """ 44 | def postOrder(root, ans): 45 | if root: 46 | postOrder(root.left, ans) 47 | postOrder(root.right, ans) 48 | ans.append(root.val) 49 | 50 | ans = [] 51 | postOrder(root, ans) 52 | return ans 53 | 54 | -------------------------------------------------------------------------------- /06.Tree/236.二叉树的最近公共祖先.前序.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=236 lang=cpp 3 | * 4 | * [236] 二叉树的最近公共祖先 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * struct TreeNode { 11 | * int val; 12 | * TreeNode *left; 13 | * TreeNode *right; 14 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 15 | * }; 16 | */ 17 | class Solution { 18 | public: 19 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 20 | if (!root) { 21 | return nullptr; 22 | } 23 | 24 | if (root == p || root == q) { 25 | return root; 26 | } 27 | 28 | auto l = lowestCommonAncestor(root->left, p, q); 29 | auto r = lowestCommonAncestor(root->right, p, q); 30 | 31 | if (l && r) { 32 | return root; 33 | } 34 | 35 | return l ? l : r; 36 | } 37 | }; 38 | // @lc code=end 39 | -------------------------------------------------------------------------------- /06.Tree/700.二叉搜索树中的搜索.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=700 lang=python 3 | # 4 | # [700] 二叉搜索树中的搜索 5 | # 6 | # https://leetcode-cn.com/problems/search-in-a-binary-search-tree/description/ 7 | # 8 | # algorithms 9 | # Easy (75.07%) 10 | # Likes: 107 11 | # Dislikes: 0 12 | # Total Accepted: 46.4K 13 | # Total Submissions: 61.8K 14 | # Testcase Example: '[4,2,7,1,3]\n2' 15 | # 16 | # 给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。 17 | # 18 | # 例如, 19 | # 20 | # 21 | # 给定二叉搜索树: 22 | # 23 | # ⁠ 4 24 | # ⁠ / \ 25 | # ⁠ 2 7 26 | # ⁠ / \ 27 | # ⁠ 1 3 28 | # 29 | # 和值: 2 30 | # 31 | # 32 | # 你应该返回如下子树: 33 | # 34 | # 35 | # ⁠ 2 36 | # ⁠ / \ 37 | # ⁠ 1 3 38 | # 39 | # 40 | # 在上述示例中,如果要找的值是 5,但因为没有节点值为 5,我们应该返回 NULL。 41 | # 42 | # 43 | 44 | # @lc code=start 45 | # Definition for a binary tree node. 46 | # class TreeNode(object): 47 | # def __init__(self, val=0, left=None, right=None): 48 | # self.val = val 49 | # self.left = left 50 | # self.right = right 51 | class Solution(object): 52 | def searchBST(self, root, val): 53 | while root: 54 | if root.val == val: 55 | return root 56 | elif root.val < val: 57 | root = root.right 58 | else: 59 | root = root.left 60 | return None 61 | # @lc code=end 62 | 63 | -------------------------------------------------------------------------------- /06.Tree/876.链表的中间结点.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=876 lang=python 3 | # 4 | # [876] 链表的中间结点 5 | # 6 | # https://leetcode-cn.com/problems/middle-of-the-linked-list/description/ 7 | # 8 | # algorithms 9 | # Easy (69.94%) 10 | # Likes: 312 11 | # Dislikes: 0 12 | # Total Accepted: 96.4K 13 | # Total Submissions: 137.9K 14 | # Testcase Example: '[1,2,3,4,5]' 15 | # 16 | # 给定一个头结点为 head 的非空单链表,返回链表的中间结点。 17 | # 18 | # 如果有两个中间结点,则返回第二个中间结点。 19 | # 20 | # 21 | # 22 | # 示例 1: 23 | # 24 | # 25 | # 输入:[1,2,3,4,5] 26 | # 输出:此列表中的结点 3 (序列化形式:[3,4,5]) 27 | # 返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。 28 | # 注意,我们返回了一个 ListNode 类型的对象 ans,这样: 29 | # ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = 30 | # NULL. 31 | # 32 | # 33 | # 示例 2: 34 | # 35 | # 36 | # 输入:[1,2,3,4,5,6] 37 | # 输出:此列表中的结点 4 (序列化形式:[4,5,6]) 38 | # 由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。 39 | # 40 | # 41 | # 42 | # 43 | # 提示: 44 | # 45 | # 46 | # 给定链表的结点数介于 1 和 100 之间。 47 | # 48 | # 49 | # 50 | 51 | # @lc code=start 52 | # Definition for singly-linked list. 53 | # class ListNode(object): 54 | # def __init__(self, x): 55 | # self.val = x 56 | # self.next = None 57 | 58 | class Solution(object): 59 | def middleNode(self, head): 60 | s1 = head 61 | s2 = head 62 | 63 | while (s2 and s2.next): 64 | s1 = s1.next 65 | s2 = s2.next.next 66 | 67 | return s1 68 | 69 | # @lc code=end 70 | 71 | -------------------------------------------------------------------------------- /07.UF/1168.大楼通网.py: -------------------------------------------------------------------------------- 1 | class UF(object): 2 | def __init__(self, N): 3 | self.F = [0] * N 4 | self.Cnt = [0] * N 5 | for i in range(N): 6 | self.F[i] = i 7 | self.Cnt[i] = 1 8 | 9 | self.count = N 10 | 11 | def Find(self, x): 12 | if x == self.F[x]: 13 | return x 14 | self.F[x] = self.Find(self.F[x]) 15 | return self.F[x] 16 | 17 | def Union(self, x, y): 18 | xpar = self.Find(x) 19 | ypar = self.Find(y) 20 | if xpar != ypar: 21 | self.F[xpar] = ypar 22 | self.Cnt[ypar] += self.Cnt[xpar] 23 | self.count -= 1 24 | 25 | -------------------------------------------------------------------------------- /07.UF/P1287.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | class UF(object): 4 | def __init__(self, N): 5 | self.F = [0] * N 6 | for i in range(N): 7 | self.F[i] = i 8 | self.totalCost = 0 9 | 10 | def Find(self, x): 11 | if x == self.F[x]: 12 | return x 13 | self.F[x] = self.Find(self.F[x]) 14 | return self.F[x] 15 | 16 | def Union(self, x, y, cost): 17 | xpar = self.Find(x) 18 | ypar = self.Find(y) 19 | if xpar != ypar: 20 | self.F[xpar] = ypar 21 | self.totalCost += cost 22 | 23 | class MST(object): 24 | def solve(self, N, es): 25 | es = sorted(es, key=(lambda x:x[2])) 26 | 27 | uf = UF(N + 1) 28 | for e in es: 29 | uf.Union(e[0], e[1], e[2]) 30 | 31 | return uf.totalCost 32 | 33 | while True: 34 | line = raw_input() 35 | ws = line.split() 36 | if len(ws) == 1 and int(ws[0]) == 0: 37 | break 38 | 39 | P = int(ws[0]) 40 | R = int(ws[1]) 41 | 42 | es = [] 43 | for i in range(R): 44 | line = raw_input() 45 | ws = line.split() 46 | f, t, cost = ws 47 | es.append([int(f), int(t), int(cost)]) 48 | 49 | mst = MST() 50 | print mst.solve(P, es) 51 | 52 | 53 | raw_input() 54 | -------------------------------------------------------------------------------- /07.UF/T1260.py: -------------------------------------------------------------------------------- 1 | # https://nanti.jisuanke.com/t/T1260 2 | 3 | class UF(object): 4 | def __init__(self, N): 5 | self.F = [0] * N 6 | self.Cnt = [0] * N 7 | for i in range(N): 8 | self.F[i] = i 9 | self.Cnt[i] = 1 10 | 11 | self.count = N 12 | 13 | def Find(self, x): 14 | if x == self.F[x]: 15 | return x 16 | self.F[x] = self.Find(self.F[x]) 17 | return self.F[x] 18 | 19 | def Union(self, x, y): 20 | xpar = self.Find(x) 21 | ypar = self.Find(y) 22 | if xpar != ypar: 23 | self.F[xpar] = ypar 24 | self.Cnt[ypar] += self.Cnt[xpar] 25 | self.count -= 1 26 | 27 | def Size(self, i): 28 | return self.Cnt[self.Find(i)] 29 | 30 | def Count(self): 31 | return self.count 32 | 33 | 34 | test = 0 35 | while True: 36 | line = raw_input() 37 | ws = line.split() 38 | n = int(ws[0]) 39 | m = int(ws[1]) 40 | 41 | if n == 0 and m == 0: 42 | break 43 | 44 | uf = UF(n + 1) 45 | 46 | for i in range(m): 47 | line = raw_input() 48 | ws = line.split() 49 | a = int(ws[0]) 50 | b = int(ws[1]) 51 | 52 | uf.Union(a,b) 53 | 54 | test += 1 55 | 56 | print 'Case %s: %s' % (test, uf.count) -------------------------------------------------------------------------------- /07.UF/并查集模板.cpp: -------------------------------------------------------------------------------- 1 | // 并查集数组 2 | vector F; 3 | // 记录并查集中集合的个数 4 | int count = 0; 5 | // 记录集合中点的个数,比如要知道i所在集合的点有多少个: C[Find(i)] 6 | // 注意:这里不能直接使用C[i] 7 | // 因为只有根结点的统计才是正确的 8 | vector Cnt; 9 | 10 | // 并查集的初始化 11 | void Init(int n) { 12 | F.resize(n); 13 | Cnt.resize(n); 14 | for (int i = 0; i < n; i++) { 15 | F[i] = i; 16 | Cnt[i] = 1; 17 | } 18 | count = n; 19 | } 20 | 21 | int Find(int x) { return x == F[x] ? x : F[x] = Find(F[x]); } 22 | 23 | void Union(int x, int y) { 24 | int xpar = Find(x); 25 | int ypar = Find(y); 26 | // 将x所在集合,合并到y所在集合 27 | if (xpar != ypar) { 28 | F[xpar] = ypar; 29 | // y集合里面的个数要增加 30 | Cnt[ypar] += Cnt[xpar]; 31 | count--; 32 | } 33 | } 34 | 35 | int Size(int i) { return Cnt[Find(i)]; } 36 | -------------------------------------------------------------------------------- /07.UF/并查集模板.java: -------------------------------------------------------------------------------- 1 | 2 | // 并查集数组 3 | int[] F = null; 4 | // 记录并查集中集合的个数 5 | int count = 0; 6 | // 记录集合中点的个数,比如要知道i所在集合的点有多少个: C[Find(i)] 7 | // 注意:这里不能直接使用C[i] 8 | // 因为只有根结点的统计才是正确的 9 | int[] Cnt = null; 10 | 11 | 12 | // 并查集的初始化 13 | void Init(int n) { 14 | F = new int[n]; 15 | Cnt = new int[n]; 16 | for (int i = 0; i < n; i++) { 17 | F[i] = i; 18 | Cnt[i] = 1; 19 | } 20 | count = n; 21 | } 22 | 23 | 24 | int Find(int x) { 25 | if (x == F[x]) { 26 | return x; 27 | } 28 | F[x] = Find(F[x]); 29 | return F[x]; 30 | } 31 | 32 | 33 | void Union(int x, int y) { 34 | int xpar = Find(x); 35 | int ypar = Find(y); 36 | // 将x所在集合,合并到y所在集合 37 | if (xpar != ypar) { 38 | F[xpar] = ypar; 39 | // y集合里面的个数要增加 40 | Cnt[ypar] += Cnt[xpar]; 41 | count--; 42 | } 43 | } 44 | 45 | 46 | int Size(int i) { 47 | return Cnt[Find(i); 48 | } 49 | 50 | 51 | -------------------------------------------------------------------------------- /07.UF/并查集模板.py: -------------------------------------------------------------------------------- 1 | class UF(object): 2 | def __init__(self, N): 3 | self.F = [0] * N 4 | self.Cnt = [0] * N 5 | for i in range(N): 6 | self.F[i] = i 7 | self.Cnt[i] = 1 8 | 9 | self.count = N 10 | 11 | def Find(self, x): 12 | if x == self.F[x]: 13 | return x 14 | self.F[x] = self.Find(self.F[x]) 15 | return self.F[x] 16 | 17 | def Union(self, x, y): 18 | xpar = self.Find(x) 19 | ypar = self.Find(y) 20 | if xpar != ypar: 21 | self.F[xpar] = ypar 22 | self.Cnt[ypar] += self.Cnt[xpar] 23 | self.count -= 1 24 | 25 | def Size(self, i): 26 | return self.Cnt[self.Find(i)] 27 | 28 | def Count(self): 29 | return self.count 30 | 31 | -------------------------------------------------------------------------------- /08.Sort/136.只出现一次的数字.bitops.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=136 lang=cpp 3 | * 4 | * [136] 只出现一次的数字 5 | */ 6 | 7 | // @lc code=start 8 | class Solution { 9 | public: 10 | int singleNumber(vector& A) { 11 | int ans = 0; 12 | for (auto& x : A) ans ^= x; 13 | return ans; 14 | } 15 | }; 16 | // @lc code=end 17 | -------------------------------------------------------------------------------- /08.Sort/21.合并两个有序链表.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=21 lang=cpp 3 | * 4 | * [21] 合并两个有序链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * struct ListNode { 11 | * int val; 12 | * ListNode *next; 13 | * ListNode() : val(0), next(nullptr) {} 14 | * ListNode(int x) : val(x), next(nullptr) {} 15 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 16 | * }; 17 | */ 18 | class Solution { 19 | public: 20 | ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { 21 | ListNode dummy, *tail = &dummy; 22 | while (l1 || l2) { 23 | if (!l2 || l1 && l1->val < l2->val) { 24 | auto back = l1->next; 25 | 26 | tail->next = l1; 27 | tail = l1; 28 | 29 | l1 = back; 30 | } else { 31 | auto back = l2->next; 32 | 33 | tail->next = l2; 34 | tail = l2; 35 | 36 | l2 = back; 37 | } 38 | } 39 | tail->next = nullptr; 40 | return dummy.next; 41 | } 42 | }; 43 | // @lc code=end 44 | -------------------------------------------------------------------------------- /08.Sort/21.合并两个有序链表.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=21 lang=java 3 | * 4 | * [21] 合并两个有序链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * public class ListNode { 11 | * int val; 12 | * ListNode next; 13 | * ListNode() {} 14 | * ListNode(int val) { this.val = val; } 15 | * ListNode(int val, ListNode next) { this.val = val; this.next = next; } 16 | * } 17 | */ 18 | class Solution { 19 | public ListNode mergeTwoLists(ListNode l1, ListNode l2) { 20 | ListNode dummy = new ListNode(); 21 | ListNode tail = dummy; 22 | 23 | while (l1 != null || l2 != null) { 24 | if (l2 == null || l1 != null && l1.val <= l2.val) { 25 | ListNode back = l1.next; 26 | 27 | tail.next = l1; 28 | tail = l1; 29 | 30 | l1 = back; 31 | } else { 32 | ListNode back = l2.next; 33 | 34 | tail.next = l2; 35 | tail = l2; 36 | 37 | l2 = back; 38 | } 39 | } 40 | tail.next = null; 41 | 42 | return dummy.next; 43 | } 44 | } 45 | // @lc code=end 46 | 47 | -------------------------------------------------------------------------------- /08.Sort/21.合并两个有序链表.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=21 lang=python 3 | # 4 | # [21] 合并两个有序链表 5 | # 6 | 7 | # @lc code=start 8 | # Definition for singly-linked list. 9 | # class ListNode(object): 10 | # def __init__(self, val=0, next=None): 11 | # self.val = val 12 | # self.next = next 13 | 14 | 15 | class Solution(object): 16 | def mergeTwoLists(self, l1, l2): 17 | """ 18 | :type l1: ListNode 19 | :type l2: ListNode 20 | :rtype: ListNode 21 | """ 22 | 23 | dummy = ListNode() 24 | tail = dummy 25 | 26 | while l1 or l2: 27 | if not l2 or (l1 and l1.val <= l2.val): 28 | back = l1.next 29 | 30 | tail.next = l1 31 | tail = l1 32 | 33 | l1 = back 34 | else: 35 | back = l2.next 36 | 37 | tail.next = l2 38 | tail = l2 39 | 40 | l2 = back 41 | tail.next = None 42 | 43 | return dummy.next 44 | 45 | # @lc code=end 46 | -------------------------------------------------------------------------------- /08.Sort/283.移动零.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=283 lang=cpp 3 | * 4 | * [283] 移动零 5 | * 6 | * https://leetcode-cn.com/problems/move-zeroes/description/ 7 | * 8 | * algorithms 9 | * Easy (63.59%) 10 | * Likes: 925 11 | * Dislikes: 0 12 | * Total Accepted: 301.5K 13 | * Total Submissions: 474.2K 14 | * Testcase Example: '[0,1,0,3,12]' 15 | * 16 | * 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 17 | * 18 | * 示例: 19 | * 20 | * 输入: [0,1,0,3,12] 21 | * 输出: [1,3,12,0,0] 22 | * 23 | * 说明: 24 | * 25 | * 26 | * 必须在原数组上操作,不能拷贝额外的数组。 27 | * 尽量减少操作次数。 28 | * 29 | * 30 | */ 31 | 32 | // @lc code=start 33 | class Solution { 34 | public: 35 | void moveZeroes(vector& A) { 36 | // [0..l)[l...i) [i...r](r...) 37 | // 对应三个区间 38 | // [非0 )[全0) [未处理的...) 39 | int l = 0, i = 0; 40 | while (i < A.size()) { 41 | if (A[i] != 0) { 42 | swap(A[l++], A[i++]); 43 | } else { 44 | i++; 45 | } 46 | } 47 | } 48 | 49 | }; 50 | // @lc code=end 51 | 52 | -------------------------------------------------------------------------------- /08.Sort/283.移动零.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=283 lang=java 3 | * 4 | * [283] 移动零 5 | * 6 | * https://leetcode-cn.com/problems/move-zeroes/description/ 7 | * 8 | * algorithms 9 | * Easy (63.59%) 10 | * Likes: 925 11 | * Dislikes: 0 12 | * Total Accepted: 301.5K 13 | * Total Submissions: 474.2K 14 | * Testcase Example: '[0,1,0,3,12]' 15 | * 16 | * 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 17 | * 18 | * 示例: 19 | * 20 | * 输入: [0,1,0,3,12] 21 | * 输出: [1,3,12,0,0] 22 | * 23 | * 说明: 24 | * 25 | * 26 | * 必须在原数组上操作,不能拷贝额外的数组。 27 | * 尽量减少操作次数。 28 | * 29 | * 30 | */ 31 | 32 | // @lc code=start 33 | class Solution { 34 | public void moveZeroes(int[] A) { 35 | int l = 0, i = 0; 36 | while (i < A.length) { 37 | if (A[i] != 0) { 38 | int t = A[l]; 39 | A[l] = A[i]; 40 | A[i] = t; 41 | i += 1; 42 | l += 1; 43 | } else { 44 | i++; 45 | } 46 | } 47 | } 48 | } 49 | // @lc code=end 50 | 51 | -------------------------------------------------------------------------------- /08.Sort/283.移动零.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=283 lang=python 3 | # 4 | # [283] 移动零 5 | # 6 | # https://leetcode-cn.com/problems/move-zeroes/description/ 7 | # 8 | # algorithms 9 | # Easy (63.59%) 10 | # Likes: 925 11 | # Dislikes: 0 12 | # Total Accepted: 301.5K 13 | # Total Submissions: 474.2K 14 | # Testcase Example: '[0,1,0,3,12]' 15 | # 16 | # 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 17 | # 18 | # 示例: 19 | # 20 | # 输入: [0,1,0,3,12] 21 | # 输出: [1,3,12,0,0] 22 | # 23 | # 说明: 24 | # 25 | # 26 | # 必须在原数组上操作,不能拷贝额外的数组。 27 | # 尽量减少操作次数。 28 | # 29 | # 30 | # 31 | 32 | # @lc code=start 33 | class Solution(object): 34 | def moveZeroes(self, A): 35 | N = len(A) if A else 0 36 | 37 | i = 0 38 | l = 0 39 | while i < N: 40 | if A[i] != 0: 41 | t = A[i] 42 | A[i] = A[l] 43 | A[l] = t 44 | i += 1 45 | l += 1 46 | else: 47 | i += 1 48 | # @lc code=end 49 | 50 | -------------------------------------------------------------------------------- /08.Sort/786.第k个数.heap.cpp: -------------------------------------------------------------------------------- 1 | // https://www.acwing.com/problem/content/description/788/ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | using namespace std; 22 | 23 | 24 | int N; 25 | int K; 26 | int A[100001]; 27 | 28 | int main(void) { 29 | while (scanf("%d%d", &N, &K) != EOF) { 30 | for (int i = 0; i < N; i++) { 31 | scanf("%d", A + i); 32 | } 33 | 34 | priority_queue Q; 35 | for (int i = 0; i < N; i++) { 36 | Q.push(A[i]); 37 | while (Q.size() > K) { 38 | Q.pop(); 39 | } 40 | } 41 | printf("%d\n", Q.top()); 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /08.Sort/786.第k个数.heap.java: -------------------------------------------------------------------------------- 1 | // https://www.acwing.com/problem/content/description/788/ 2 | import java.io.*; 3 | import java.util.*; 4 | 5 | public class Main { 6 | static int[] A = new int[100001]; 7 | public static void main(String args[]) throws Exception { 8 | Scanner sc = new Scanner(System.in); 9 | int n = sc.nextInt(); 10 | int k = sc.nextInt(); 11 | 12 | for (int i = 0; i < n; i++) { 13 | A[i] = sc.nextInt(); 14 | } 15 | // 这里用最大堆 16 | Queue Q = new PriorityQueue<>((v1, v2) -> v2 - v1); 17 | for (int i = 0; i < n; i++) { 18 | final int x = A[i]; 19 | Q.offer(x); 20 | while (Q.size() > k) { 21 | Q.poll(); 22 | } 23 | } 24 | System.out.println(Q.peek()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /08.Sort/786.第k个数.heap.py: -------------------------------------------------------------------------------- 1 | # https://www.acwing.com/problem/content/description/788/ 2 | import Queue 3 | from Queue import PriorityQueue 4 | 5 | s = raw_input().split() 6 | n = int(s[0]) 7 | k = int(s[1]) 8 | s = raw_input().split() 9 | A = [int(x) for x in s] 10 | 11 | Q = PriorityQueue() 12 | for x in A: 13 | Q.put(-x) 14 | while Q.qsize() > k: 15 | Q.get() 16 | 17 | print 0-Q.get() 18 | 19 | 20 | -------------------------------------------------------------------------------- /08.Sort/786.第k个数.py: -------------------------------------------------------------------------------- 1 | # https://www.acwing.com/problem/content/description/788/ 2 | def swap(A, i, j): 3 | t = A[i] 4 | A[i] = A[j] 5 | A[j] = t 6 | 7 | def kth(A, b, e, k): 8 | if b >= e: 9 | return 0 10 | 11 | if b + 1 >= e: 12 | return A[b] 13 | 14 | x = A[b + ((e - b) >> 1)] 15 | i = b 16 | l = b 17 | r = e - 1 18 | 19 | while i <= r: 20 | if A[i] < x: 21 | swap(A, l, i) 22 | i += 1 23 | l += 1 24 | elif (A[i] == x): 25 | i += 1 26 | else: 27 | swap(A, r, i) 28 | r -= 1 29 | 30 | lcnt = l - b 31 | mcnt = i - l 32 | 33 | if k < lcnt: 34 | return kth(A, b, l, k) 35 | if k >= (lcnt + mcnt): 36 | return kth(A, i, e, k - lcnt - mcnt) 37 | return x 38 | 39 | def kthNumber(A, n, k): 40 | return kth(A, 0, n, k - 1) 41 | 42 | s = raw_input().split() 43 | n = int(s[0]) 44 | k = int(s[1]) 45 | s = raw_input().split() 46 | A = [int(x) for x in s] 47 | print kthNumber(A, n, k) 48 | 49 | 50 | -------------------------------------------------------------------------------- /08.Sort/88.合并两个有序数组.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=88 lang=java 3 | * 4 | * [88] 合并两个有序数组 5 | * 6 | * https://leetcode-cn.com/problems/merge-sorted-array/description/ 7 | * 8 | * algorithms 9 | * Easy (49.20%) 10 | * Likes: 745 11 | * Dislikes: 0 12 | * Total Accepted: 259.6K 13 | * Total Submissions: 527.7K 14 | * Testcase Example: '[1,2,3,0,0,0]\n3\n[2,5,6]\n3' 15 | * 16 | * 给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。 17 | * 18 | * 初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 19 | * nums2 的元素。 20 | * 21 | * 22 | * 23 | * 示例 1: 24 | * 25 | * 26 | * 输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 27 | * 输出:[1,2,2,3,5,6] 28 | * 29 | * 30 | * 示例 2: 31 | * 32 | * 33 | * 输入:nums1 = [1], m = 1, nums2 = [], n = 0 34 | * 输出:[1] 35 | * 36 | * 37 | * 38 | * 39 | * 提示: 40 | * 41 | * 42 | * nums1.length == m + n 43 | * nums2.length == n 44 | * 0 45 | * 1 46 | * -10^9 47 | * 48 | * 49 | */ 50 | 51 | // @lc code=start 52 | class Solution { 53 | public void merge(int[] A, int m, int[] B, int n) { 54 | int tail = n + m - 1; 55 | int i = m - 1; 56 | int j = n - 1; 57 | while (i >= 0 || j >= 0) { 58 | if (j < 0 || (i >= 0 && A[i] >= B[j])) { 59 | A[tail--] = A[i--]; 60 | } else { 61 | A[tail--] = B[j--]; 62 | } 63 | } 64 | } 65 | } 66 | // @lc code=end 67 | 68 | -------------------------------------------------------------------------------- /08.Sort/mergeSort.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | void msort(vector &a, int b, int e, vector &t) { 3 | if (b >= e || b + 1 >= e) { 4 | return; 5 | } 6 | 7 | const int m = b + ((e - b) >> 1); 8 | 9 | msort(a, b, m, t); 10 | msort(a, m, e, t); 11 | 12 | int i = b; 13 | int j = m; 14 | int to = b; 15 | 16 | while (i < m || j < e) { 17 | if (j >= e || i < m && a[i] <= a[j]) { 18 | t[to++] = a[i++]; 19 | } else { 20 | t[to++] = a[j++]; 21 | } 22 | } 23 | 24 | for (int i = b; i < e; i++) { 25 | a[i] = t[i]; 26 | } 27 | } 28 | 29 | public: 30 | void mergeSort(vector &nums) { 31 | vector t(nums.size()); 32 | msort(nums, 0, nums.size(), t); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /08.Sort/mergeSort.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private void msort(int[] a, int b, int e, int t[]) { 3 | // 空区间 4 | if (b >= e) { 5 | return; 6 | } 7 | // 空区间中只有一个结点 8 | if (b + 1 == e) { 9 | return; 10 | } 11 | // 分成两半, 二叉树可以自动取得root.left, root.right 12 | // 这里我们需要通过计算来得到左右子数组。 13 | final int m = b + ((e - b) >> 1); 14 | 15 | // 类比二叉树分别遍历左子树和右子树。 16 | msort(a, b, m, t); 17 | msort(a, m, e, t); 18 | 19 | int i = b; 20 | int j = m; 21 | int to = b; 22 | 23 | // 将两个子数组进行合并, 注意下面是一个很重要的模板 24 | while (i < m || j < e) { 25 | if (j >= e || i < m && a[i] <= a[j]) { 26 | t[to++] = a[i++]; 27 | } else { 28 | t[to++] = a[j++]; 29 | } 30 | } 31 | // 把合并的结果拷回原来的数组a[] 32 | for (i = b; i < e; i++) { 33 | a[i] = t[i]; 34 | } 35 | } 36 | public void mergeSort(int[] nums) { 37 | // 如果传进来的数组为空 38 | if (nums == null || nums.length == 0) { 39 | return; 40 | } 41 | // t是一个临时中转的数组 42 | int[] t = new int[nums.length]; 43 | msort(nums, 0, nums.length, t); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /08.Sort/mergeSort.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def mergeSort(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: None Do not return anything, modify nums in-place instead. 6 | """ 7 | if not nums or len(nums) == 0: 8 | return 9 | 10 | t = [0] * len(nums) 11 | 12 | def msort(a, b, e, t): 13 | if b >= e or b + 1 >= e: 14 | return 15 | 16 | m = b + ((e-b)>>1) 17 | msort(a, b, m, t) 18 | msort(a, m, e, t) 19 | 20 | i = b 21 | j = m 22 | to = b 23 | 24 | while i < m or j < e: 25 | if j >= e or (i < m and a[i] <= a[j]): 26 | t[to] = a[i] 27 | to += 1 28 | i += 1 29 | else: 30 | t[to] = a[j] 31 | to += 1 32 | j += 1 33 | 34 | for i in range(b, e): 35 | a[i] = t[i] 36 | msort(nums, 0, len(nums), t) 37 | -------------------------------------------------------------------------------- /08.Sort/reversePairs.cpp: -------------------------------------------------------------------------------- 1 | 2 | class Solution { 3 | void msort(vector &a, int b, int e, vector &t, int &cnt) { 4 | if (b >= e || b + 1 >= e) { 5 | return; 6 | } 7 | const int m = b + ((e - b) >> 1); 8 | msort(a, b, m, t, cnt); 9 | msort(a, m, e, t, cnt); 10 | 11 | int i = b; 12 | int j = m; 13 | int to = b; 14 | 15 | while (i < m || j < e) { 16 | if (j >= e || i < m && a[i] <= a[j]) { 17 | t[to++] = a[i++]; 18 | cnt += j - m; 19 | } else { 20 | t[to++] = a[j++]; 21 | } 22 | } 23 | 24 | for (int i = b; i < e; i++) { 25 | a[i] = t[i]; 26 | } 27 | } 28 | 29 | public: 30 | int reversePairs(vector &nums) { 31 | int cnt = 0; 32 | vector t(nums.size()); 33 | msort(nums, 0, nums.size(), t, cnt); 34 | return cnt; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /08.Sort/reversePairs.java: -------------------------------------------------------------------------------- 1 | // 不同的测试平台可能代码会有一些小修改 2 | // 测试链接: 3 | // https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/submissions/ 4 | // https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=13 5 | // https://www.lintcode.com/problem/reverse-pairs/description 6 | 7 | class Solution { 8 | private int cnt = 0; 9 | 10 | private void msort(int[] a, int b, int e, int[] t) { 11 | if (b >= e || b + 1 >= e) { 12 | return; 13 | } 14 | 15 | final int m = b + ((e - b) >> 1); 16 | 17 | msort(a, b, m, t); 18 | msort(a, m, e, t); 19 | 20 | int i = b; 21 | int j = m; 22 | int to = b; 23 | 24 | while (i < m || j < e) { 25 | if (j >= e || i < m && a[i] <= a[j]) { 26 | t[to++] = a[i++]; 27 | cnt += j - m; // 是的,就在这里加一行代码就可以了。 28 | } else { 29 | t[to++] = a[j++]; 30 | } 31 | } 32 | 33 | for (i = b; i < e; i++) { 34 | a[i] = t[i]; 35 | } 36 | } 37 | public int reversePairs(int[] nums) { 38 | if (nums == null || nums.length <= 1) { 39 | return 0; 40 | } 41 | int[] t = new int[nums.length]; 42 | cnt = 0; 43 | msort(nums, 0, nums.length, t); 44 | return cnt; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /08.Sort/reversePairs.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def reversePairs(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: None Do not return anything, modify nums in-place instead. 6 | """ 7 | if not nums or len(nums) == 0: 8 | return 0 9 | 10 | t = [0] * len(nums) 11 | cnt = [0] 12 | 13 | def msort(a, b, e, t, cnt): 14 | if b >= e or b + 1 >= e: 15 | return 16 | 17 | m = b + ((e-b)>>1) 18 | msort(a, b, m, t, cnt) 19 | msort(a, m, e, t, cnt) 20 | 21 | i = b 22 | j = m 23 | to = b 24 | 25 | while i < m or j < e: 26 | if j >= e or (i < m and a[i] <= a[j]): 27 | t[to] = a[i] 28 | to += 1 29 | i += 1 30 | cnt[0] += j - m 31 | else: 32 | t[to] = a[j] 33 | to += 1 34 | j += 1 35 | 36 | for i in range(b, e): 37 | a[i] = t[i] 38 | 39 | msort(nums, 0, len(nums), t, cnt) 40 | 41 | return cnt[0] 42 | -------------------------------------------------------------------------------- /08.Sort/seqNumber.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | void msort(vector &a, int b, int e, vector &t, int &cnt) { 3 | if (b >= e || b + 1 >= e) { 4 | return; 5 | } 6 | const int m = b + ((e - b) >> 1); 7 | msort(a, b, m, t, cnt); 8 | msort(a, m, e, t, cnt); 9 | 10 | int i = b; 11 | int j = m; 12 | int to = b; 13 | 14 | while (i < m || j < e) { 15 | if (j >= e || i < m && a[i] <= a[j]) { 16 | t[to++] = a[i++]; 17 | } else { 18 | t[to++] = a[j++]; 19 | cnt += i - b; 20 | } 21 | } 22 | 23 | for (int i = b; i < e; i++) { 24 | a[i] = t[i]; 25 | } 26 | } 27 | 28 | public: 29 | int seqNumber(vector &nums) { 30 | int cnt = 0; 31 | vector t(nums.size()); 32 | msort(nums, 0, nums.size(), t, cnt); 33 | return cnt; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /08.Sort/seqNumber.java: -------------------------------------------------------------------------------- 1 | // 顺序对 2 | class Solution { 3 | private int cnt = 0; 4 | 5 | private void msort(int[] a, int b, int e, int[] t) { 6 | if (b >= e || b + 1 >= e) { 7 | return; 8 | } 9 | 10 | final int m = b + ((e - b) >> 1); 11 | 12 | msort(a, b, m, t); 13 | msort(a, m, e, t); 14 | 15 | int i = b; 16 | int j = m; 17 | int to = b; 18 | 19 | while (i < m || j < e) { 20 | if (j >= e || i < m && a[i] <= a[j]) { 21 | t[to++] = a[i++]; 22 | } else { 23 | t[to++] = a[j++]; 24 | cnt += i - b; // 是的,就在这里加一行代码就可以了。 25 | } 26 | } 27 | 28 | for (i = b; i < e; i++) { 29 | a[i] = t[i]; 30 | } 31 | } 32 | 33 | public int seqNumber(int[] nums) { 34 | if (nums == null || nums.length <= 1) { 35 | return 0; 36 | } 37 | int[] t = new int[nums.length]; 38 | cnt = 0; 39 | msort(nums, 0, nums.length, t); 40 | return cnt; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /08.Sort/seqNumber.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def seqNumber(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: None Do not return anything, modify nums in-place instead. 6 | """ 7 | if not nums or len(nums) == 0: 8 | return 0 9 | 10 | t = [0] * len(nums) 11 | cnt = [0] 12 | 13 | def msort(a, b, e, t, cnt): 14 | if b >= e or b + 1 >= e: 15 | return 16 | 17 | m = b + ((e-b)>>1) 18 | msort(a, b, m, t, cnt) 19 | msort(a, m, e, t, cnt) 20 | 21 | i = b 22 | j = m 23 | to = b 24 | 25 | while i < m or j < e: 26 | if j >= e or (i < m and a[i] <= a[j]): 27 | t[to] = a[i] 28 | to += 1 29 | i += 1 30 | else: 31 | t[to] = a[j] 32 | to += 1 33 | j += 1 34 | cnt[0] += i - b 35 | 36 | for i in range(b, e): 37 | a[i] = t[i] 38 | msort(nums, 0, len(nums), t, cnt) 39 | 40 | return cnt[0] 41 | -------------------------------------------------------------------------------- /09.BinarySearch/154.寻找旋转排序数组中的最小值-ii.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=154 lang=java 3 | * 4 | * [154] 寻找旋转排序数组中的最小值 II 5 | */ 6 | 7 | // @lc code=start 8 | class Solution { 9 | public int findMin(int[] A) { 10 | final int N = A == null ? 0 : A.length; 11 | // 由于要使用A[r-1] 12 | // 这里直接用了闭区间[l, r] 13 | int l = 0, r = N - 1; 14 | // 保证区间中至少有一个元素 15 | while (l < r) { 16 | final int m = l + ((r - l) >> 1); 17 | // 如果A[m] < A[r] 18 | // 表示A[m]掉在了右边的区间 19 | // 那么此时[m + 1, r]可以不要了 20 | if (A[m] < A[r]) { 21 | // 保留区间[l, m] 22 | r = m; 23 | } else if (A[m] > A[r]) { 24 | // 当A[m] > A[r]时 25 | // A[m]掉在左边的区间 26 | // 此时[l, m]可以不要了 27 | // 保留区间[m + 1, r] 28 | l = m + 1; 29 | } else { 30 | // 如果与右边元素相等,此时r与m不相等的 31 | // 那么扔掉A[r] 32 | r--; 33 | } 34 | } 35 | return A[l]; 36 | } 37 | } 38 | // @lc code=end 39 | 40 | -------------------------------------------------------------------------------- /09.BinarySearch/33.搜索旋转排序数组.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=33 lang=cpp 3 | * 4 | * [33] 搜索旋转排序数组 5 | */ 6 | 7 | // @lc code=start 8 | class Solution { 9 | public: 10 | int search(vector& A, int T) { 11 | const int N = A.size(); 12 | int l = 0, r = N; 13 | 14 | while (l < r) { 15 | const int m = l + ((r - l) >> 1); 16 | 17 | if (A[l] == T) return l; 18 | if (A[m] == T) return m; 19 | if (A[r - 1] == T) return r - 1; 20 | 21 | if (A[l] < A[m]) { 22 | if (A[l] < T && T < A[m]) { 23 | r = m; 24 | } else { 25 | l = m + 1; 26 | } 27 | } else { 28 | if (A[m] < T && T < A[r - 1]) { 29 | l = m + 1; 30 | } else { 31 | r = m; 32 | } 33 | } 34 | } 35 | 36 | return -1; 37 | } 38 | }; 39 | // @lc code=end 40 | -------------------------------------------------------------------------------- /09.BinarySearch/35.搜索插入位置.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=35 lang=cpp 3 | * 4 | * [35] 搜索插入位置 5 | * 6 | * https://leetcode-cn.com/problems/search-insert-position/description/ 7 | * 8 | * algorithms 9 | * Easy (47.00%) 10 | * Likes: 810 11 | * Dislikes: 0 12 | * Total Accepted: 314.3K 13 | * Total Submissions: 668.8K 14 | * Testcase Example: '[1,3,5,6]\n5' 15 | * 16 | * 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 17 | * 18 | * 你可以假设数组中无重复元素。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: [1,3,5,6], 5 23 | * 输出: 2 24 | * 25 | * 26 | * 示例 2: 27 | * 28 | * 输入: [1,3,5,6], 2 29 | * 输出: 1 30 | * 31 | * 32 | * 示例 3: 33 | * 34 | * 输入: [1,3,5,6], 7 35 | * 输出: 4 36 | * 37 | * 38 | * 示例 4: 39 | * 40 | * 输入: [1,3,5,6], 0 41 | * 输出: 0 42 | * 43 | * 44 | */ 45 | 46 | // @lc code=start 47 | class Solution { 48 | public: 49 | int searchInsert(vector &A, int target) { 50 | const int N = A.size(); 51 | int l = 0, r = N; 52 | while (l < r) { 53 | const int m = l + ((r - l) >> 1); 54 | if (A[m] < target) { 55 | l = m + 1; 56 | } else { 57 | r = m; 58 | } 59 | } 60 | return l; 61 | } 62 | }; 63 | // @lc code=end 64 | -------------------------------------------------------------------------------- /09.BinarySearch/35.搜索插入位置.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=35 lang=java 3 | * 4 | * [35] 搜索插入位置 5 | * 6 | * https://leetcode-cn.com/problems/search-insert-position/description/ 7 | * 8 | * algorithms 9 | * Easy (47.00%) 10 | * Likes: 810 11 | * Dislikes: 0 12 | * Total Accepted: 314.3K 13 | * Total Submissions: 668.8K 14 | * Testcase Example: '[1,3,5,6]\n5' 15 | * 16 | * 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 17 | * 18 | * 你可以假设数组中无重复元素。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: [1,3,5,6], 5 23 | * 输出: 2 24 | * 25 | * 26 | * 示例 2: 27 | * 28 | * 输入: [1,3,5,6], 2 29 | * 输出: 1 30 | * 31 | * 32 | * 示例 3: 33 | * 34 | * 输入: [1,3,5,6], 7 35 | * 输出: 4 36 | * 37 | * 38 | * 示例 4: 39 | * 40 | * 输入: [1,3,5,6], 0 41 | * 输出: 0 42 | * 43 | * 44 | */ 45 | 46 | // @lc code=start 47 | class Solution { 48 | public int searchInsert(int[] A, int target) { 49 | if (A == null || A.length <= 0) { 50 | return -1; 51 | } 52 | int l = 0, r = A.length; 53 | while (l < r) { 54 | final int m = l + ((r - l) >> 1); 55 | if (A[m] < target) { 56 | l = m + 1; 57 | } else { 58 | r = m; 59 | } 60 | } 61 | return l; 62 | } 63 | } 64 | // @lc code=end 65 | -------------------------------------------------------------------------------- /09.BinarySearch/35.搜索插入位置.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=35 lang=python 3 | # 4 | # [35] 搜索插入位置 5 | # 6 | # https://leetcode-cn.com/problems/search-insert-position/description/ 7 | # 8 | # algorithms 9 | # Easy (47.00%) 10 | # Likes: 810 11 | # Dislikes: 0 12 | # Total Accepted: 314.3K 13 | # Total Submissions: 668.8K 14 | # Testcase Example: '[1,3,5,6]\n5' 15 | # 16 | # 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 17 | # 18 | # 你可以假设数组中无重复元素。 19 | # 20 | # 示例 1: 21 | # 22 | # 输入: [1,3,5,6], 5 23 | # 输出: 2 24 | # 25 | # 26 | # 示例 2: 27 | # 28 | # 输入: [1,3,5,6], 2 29 | # 输出: 1 30 | # 31 | # 32 | # 示例 3: 33 | # 34 | # 输入: [1,3,5,6], 7 35 | # 输出: 4 36 | # 37 | # 38 | # 示例 4: 39 | # 40 | # 输入: [1,3,5,6], 0 41 | # 输出: 0 42 | # 43 | # 44 | # 45 | 46 | # @lc code=start 47 | class Solution(object): 48 | def searchInsert(self, A, target): 49 | """ 50 | :type A: List[int] 51 | :type target: int 52 | :rtype: int 53 | """ 54 | if not A or len(A) == 0: 55 | return 0 56 | 57 | l = 0 58 | r = len(A) 59 | 60 | while l < r: 61 | m = l + ((r-l)>>1) 62 | if (A[m] < target): 63 | l = m + 1 64 | else: 65 | r = m 66 | 67 | return l 68 | # @lc code=end 69 | 70 | -------------------------------------------------------------------------------- /09.BinarySearch/53.最大子序和.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=53 lang=cpp 3 | * 4 | * [53] 最大子序和 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | // @lc code=start 11 | class Solution { 12 | public: 13 | int maxSubArray(vector& B) { 14 | const int N = B.size(); 15 | int64_t pre_min_value = 0; 16 | int64_t cur_value = 0; 17 | int64_t pre_sum = 0; 18 | int64_t ans = INT_MIN; 19 | for (int i = 0; i < N; i++) { 20 | pre_sum += B[i]; 21 | cur_value = pre_sum; 22 | ans = max(cur_value - pre_min_value, ans); 23 | pre_min_value = min(pre_min_value, cur_value); 24 | } 25 | return ans; 26 | } 27 | }; 28 | // @lc code=end 29 | -------------------------------------------------------------------------------- /09.BinarySearch/53.最大子序和.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=53 lang=python 3 | # 4 | # [53] 最大子序和 5 | # 6 | # https://leetcode-cn.com/problems/maximum-subarray/description/ 7 | # 8 | # algorithms 9 | # Easy (53.24%) 10 | # Likes: 2881 11 | # Dislikes: 0 12 | # Total Bccepted: 414.9K 13 | # Total Submissions: 779.3K 14 | # Testcase Example: '[-2,1,-3,4,-1,2,1,-5,4]' 15 | # 16 | # 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 17 | # 18 | # 19 | # 20 | # 示例 1: 21 | # 22 | # 23 | # 输入:nums = [-2,1,-3,4,-1,2,1,-5,4] 24 | # 输出:6 25 | # 解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。 26 | # 27 | # 28 | # 示例 2: 29 | # 30 | # 31 | # 输入:nums = [1] 32 | # 输出:1 33 | # 34 | # 35 | # 示例 3: 36 | # 37 | # 38 | # 输入:nums = [0] 39 | # 输出:0 40 | # 41 | # 42 | # 示例 4: 43 | # 44 | # 45 | # 输入:nums = [-1] 46 | # 输出:-1 47 | # 48 | # 49 | # 示例 5: 50 | # 51 | # 52 | # 输入:nums = [-100000] 53 | # 输出:-100000 54 | # 55 | # 56 | # 57 | # 58 | # 提示: 59 | # 60 | # 61 | # 1 62 | # -10^5 63 | # 64 | # 65 | # 66 | # 67 | # 进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。 68 | # 69 | # 70 | 71 | # @lc code=start 72 | class Solution(object): 73 | def maxSubArray(self, B): 74 | N = 0 if not B else len(B) 75 | pre = 0 76 | pre_min = 0 77 | ans = -2147483648 78 | 79 | for i in range(0, N): 80 | pre += B[i] 81 | ans = max(ans, pre - pre_min) 82 | pre_min = min(pre_min, pre) 83 | return ans 84 | 85 | # @lc code=end 86 | 87 | -------------------------------------------------------------------------------- /09.BinarySearch/69.x-的平方根.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=69 lang=cpp 3 | * 4 | * [69] x 的平方根 5 | * 6 | * https://leetcode-cn.com/problems/sqrtx/description/ 7 | * 8 | * algorithms 9 | * Easy (39.16%) 10 | * Likes: 585 11 | * Dislikes: 0 12 | * Total Accepted: 253.6K 13 | * Total Submissions: 647.6K 14 | * Testcase Example: '4' 15 | * 16 | * 实现 int sqrt(int x) 函数。 17 | * 18 | * 计算并返回 x 的平方根,其中 x 是非负整数。 19 | * 20 | * 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。 21 | * 22 | * 示例 1: 23 | * 24 | * 输入: 4 25 | * 输出: 2 26 | * 27 | * 28 | * 示例 2: 29 | * 30 | * 输入: 8 31 | * 输出: 2 32 | * 说明: 8 的平方根是 2.82842..., 33 | * 由于返回类型是整数,小数部分将被舍去。 34 | * 35 | * 36 | */ 37 | 38 | // @lc code=start 39 | class Solution { 40 | public: 41 | int mySqrt(int x) { 42 | int64_t l = 0, r = x; 43 | 44 | auto getC = [](int64_t x, int64_t m) { 45 | if (m * m < x) { 46 | return -1; 47 | } else if (m * m == x) { 48 | return 0; 49 | } 50 | return 1; 51 | }; 52 | 53 | while (l < r) { 54 | const int64_t m = l + ((r - l) >> 1); 55 | const int64_t mov = getC(x, m); 56 | if (mov < 0) { 57 | l = m + 1; 58 | } else { 59 | r = m; 60 | } 61 | } 62 | 63 | // 这里如能够找到开根号之后的整数,那么这时直接返回l 64 | if (l * l == x) { 65 | return l; 66 | } 67 | // 这里如果找不到,那么由于l * l > x 68 | // 此时需要后退一步。 69 | // 因为题意要求只能取去掉小数之后的整数部分。 70 | return l - 1; 71 | } 72 | }; 73 | // @lc code=end 74 | -------------------------------------------------------------------------------- /09.BinarySearch/69.x-的平方根.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=69 lang=java 3 | * 4 | * [69] x 的平方根 5 | * 6 | * https://leetcode-cn.com/problems/sqrtx/description/ 7 | * 8 | * algorithms 9 | * Easy (39.16%) 10 | * Likes: 585 11 | * Dislikes: 0 12 | * Total Accepted: 253.6K 13 | * Total Submissions: 647.6K 14 | * Testcase Example: '4' 15 | * 16 | * 实现 int sqrt(int x) 函数。 17 | * 18 | * 计算并返回 x 的平方根,其中 x 是非负整数。 19 | * 20 | * 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。 21 | * 22 | * 示例 1: 23 | * 24 | * 输入: 4 25 | * 输出: 2 26 | * 27 | * 28 | * 示例 2: 29 | * 30 | * 输入: 8 31 | * 输出: 2 32 | * 说明: 8 的平方根是 2.82842..., 33 | * 由于返回类型是整数,小数部分将被舍去。 34 | * 35 | * 36 | */ 37 | 38 | // @lc code=start 39 | class Solution { 40 | private int getC(long x, long m) { 41 | if (m * m < x) { 42 | return -1; 43 | } else if (m * m == x) { 44 | return 0; 45 | } 46 | return 1; 47 | } 48 | 49 | public int mySqrt(int x) { 50 | int l = 0, r = x; 51 | while (l < r) { 52 | final int m = l + ((r - l) >> 1); 53 | final int mov = getC(x, m); 54 | if (mov < 0) { 55 | l = m + 1; 56 | } else { 57 | r = m; 58 | } 59 | } 60 | if (l * l == x) { 61 | return l; 62 | } 63 | // 注意,当在映射之后的数组中不存在0的时候 64 | // l的下标是指向映射之后的C[x] = 1第一个位置 65 | // 此时 l * l > m 66 | // 所以这里需要返回l - 1 67 | // 因为按照题意,需要返回整数部分。 68 | return l - 1; 69 | } 70 | } 71 | // @lc code=end 72 | -------------------------------------------------------------------------------- /09.BinarySearch/69.数组中数值和下标相等的元素.2.java: -------------------------------------------------------------------------------- 1 | // 测试平台: https://www.acwing.com/problem/content/65/ 2 | class Solution { 3 | private int getC(int[] A, int i) { 4 | final int v = A[i]; 5 | if (v < i) { 6 | return -1; 7 | } else if (v == i) { 8 | return 0; 9 | } 10 | return 1; 11 | } 12 | 13 | private int getLeftSide(int[] A) { 14 | int l = 0, r = A.length; 15 | while (l < r) { 16 | final int m = l + ((r - l) >> 1); 17 | final int mov = getC(A, m); 18 | if (mov < 0) { 19 | l = m + 1; 20 | } else { 21 | r = m; 22 | } 23 | } 24 | return l; 25 | } 26 | 27 | private int getRightSide(int[] A, int start) { 28 | int l = start, r = A.length; 29 | while (l < r) { 30 | final int m = l + ((r - l) >> 1); 31 | final int mov = getC(A, m); 32 | if (mov <= 0) { 33 | l = m + 1; 34 | } else { 35 | r = m; 36 | } 37 | } 38 | return l; 39 | } 40 | 41 | public int getNumberSameAsIndex(int[] A) { 42 | if (A == null || A.length == 0) { 43 | return -1; 44 | } 45 | final int l = getLeftSide(A); 46 | final int r = getRightSide(A, l); 47 | 48 | // 这里我们已经找到的范围就是[l, r) 49 | // 由于题意只要求随意返回相等的一个数就是可以了 50 | // 所以这里我们就随便返回一个位置的数字就可以了 51 | return l == r ? -1 : A[r-1]; 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /09.BinarySearch/69.数组中数值和下标相等的元素.cpp: -------------------------------------------------------------------------------- 1 | // 测试平台: https://www.acwing.com/problem/content/65/ 2 | class Solution { 3 | public: 4 | int getNumberSameAsIndex(vector &A) { 5 | const int N = A.size(); 6 | 7 | auto getC = [&](const int i) { 8 | const int v = A[i]; 9 | if (v < i) { 10 | return -1; 11 | } else if (v == i) { 12 | return 0; 13 | } 14 | return 1; 15 | }; 16 | 17 | int l = 0, r = N; 18 | while (l < r) { 19 | const int m = l + ((r - l) >> 1); 20 | const int mov = getC(m); 21 | if (mov < 0) { 22 | l = m + 1; 23 | } else { 24 | r = m; 25 | } 26 | } 27 | 28 | if (l < N && A[l] == l) { 29 | return l; 30 | } 31 | return -1; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /09.BinarySearch/69.数组中数值和下标相等的元素.java: -------------------------------------------------------------------------------- 1 | // 测试平台: https://www.acwing.com/problem/content/65/ 2 | class Solution { 3 | private int getC(int[] A, int i) { 4 | final int v = A[i]; 5 | if (v < i) { 6 | return -1; 7 | } else if (v == i) { 8 | return 0; 9 | } 10 | return 1; 11 | } 12 | 13 | public int getNumberSameAsIndex(int[] A) { 14 | if (A == null || A.length == 0) { 15 | return -1; 16 | } 17 | int l = 0, r = A.length; 18 | while (l < r) { 19 | final int m = l + ((r - l) >> 1); 20 | final int mov = getC(A, m); 21 | if (mov < 0) { 22 | l = m + 1; 23 | } else { 24 | r = m; 25 | } 26 | } 27 | if (l < A.length && A[l] == l) { 28 | return l; 29 | } 30 | return -1; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /09.BinarySearch/69.数组中数值和下标相等的元素.py: -------------------------------------------------------------------------------- 1 | // 测试平台: https://www.acwing.com/problem/content/65/ 2 | class Solution(object): 3 | def getNumberSameAsIndex(self, A): 4 | """ 5 | :type A: List[int] 6 | :rtype: int 7 | """ 8 | if not A or len(A) == 0: 9 | return -1 10 | l = 0 11 | r = len(A) 12 | def getC(A, i): 13 | v = A[i] 14 | if v < i: 15 | return -1 16 | elif v == i: 17 | return 0 18 | else: 19 | return 1 20 | while l < r: 21 | m = l + ((r-l)>>1) 22 | mov = getC(A, m) 23 | if mov < 0: 24 | l = m + 1 25 | else: 26 | r = m 27 | if l < len(A) and A[l] == l: 28 | return l 29 | return -1 30 | -------------------------------------------------------------------------------- /09.BinarySearch/868._子数组的最大平均值.2.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 给定一个由n个整数组成的数组,找到给定长度k的连续子数组,该子数组具有最大平均值。你需要输出最大平均值。 4 | 5 | 样例 6 | 7 | Example1 8 | 9 | Input: nums = [1,12,-5,-6,50,3] and k = 4 10 | Output: 12.75 11 | Explanation: 12 | Maximum average is (12-5-6+50)/4 = 51/4 = 12.75 13 | 14 | 15 | Example2 16 | Input: nums = [4,2,1,3,3] and k = 2 17 | Output: 3.00 18 | Explanation: 19 | Maximum average is (3+3)/2 = 6/2 = 3.00 20 | 21 | 22 | 注意事项 23 | 1 <= k <= n <= 30,000. 24 | 给定数组的元素范围是[-10,000, 10,000]。 25 | */ 26 | // 测试平台: https://www.lintcode.com/problem/maximum-average-subarray/ 27 | 28 | public class Solution { 29 | private long maxSumInKLength(int[] A, int k) { 30 | final int N = A == null ? 0 : A.length; 31 | long s = 0; 32 | long ans = Integer.MIN_VALUE; 33 | for (int i = 0; i < N; i++) { 34 | s += A[i]; 35 | if (i < k - 1) { 36 | continue; 37 | } 38 | ans = Math.max(ans, s); 39 | s -= A[i+1-k]; 40 | } 41 | return ans; 42 | } 43 | 44 | public double findMaxAverage(int[] A, int k) { 45 | long maxSum = maxSumInKLength(A, k); 46 | return (double)maxSum / (double)k; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /09.BinarySearch/868._子数组的最大平均值.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 给定一个由n个整数组成的数组,找到给定长度k的连续子数组,该子数组具有最大平均值。你需要输出最大平均值。 4 | 5 | 样例 6 | 7 | Example1 8 | 9 | Input: nums = [1,12,-5,-6,50,3] and k = 4 10 | Output: 12.75 11 | Explanation: 12 | Maximum average is (12-5-6+50)/4 = 51/4 = 12.75 13 | 14 | 15 | Example2 16 | Input: nums = [4,2,1,3,3] and k = 2 17 | Output: 3.00 18 | Explanation: 19 | Maximum average is (3+3)/2 = 6/2 = 3.00 20 | 21 | 22 | 注意事项 23 | 1 <= k <= n <= 30,000. 24 | 给定数组的元素范围是[-10,000, 10,000]。 25 | */ 26 | // 测试平台: https://www.lintcode.com/problem/maximum-average-subarray/ 27 | 28 | class Solution { 29 | public: 30 | double findMaxAverage(vector &A, int k) { 31 | // 本质上就是滑动窗口 32 | const int N = A.size(); 33 | 34 | int64_t s = 0; 35 | double avg = INT_MIN; 36 | for (int i = 0; i < N; i++) { 37 | s += A[i]; 38 | if (i < k - 1) { 39 | continue; 40 | } 41 | double tmp = (double)s / (double)k; 42 | avg = max(tmp, avg); 43 | 44 | // 当前区间为[i + 1 - k, i + 1) 45 | // 那么将要滑出窗口的元素为A[i + 1 - k] 46 | // 这个时需,需要从滑动窗口的和里面减去这个元素 47 | s -= A[i + 1 - k]; 48 | } 49 | 50 | return avg; 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /09.BinarySearch/868._子数组的最大平均值.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 给定一个由n个整数组成的数组,找到给定长度k的连续子数组,该子数组具有最大平均值。你需要输出最大平均值。 4 | 5 | 样例 6 | 7 | Example1 8 | 9 | Input: nums = [1,12,-5,-6,50,3] and k = 4 10 | Output: 12.75 11 | Explanation: 12 | Maximum average is (12-5-6+50)/4 = 51/4 = 12.75 13 | 14 | 15 | Example2 16 | Input: nums = [4,2,1,3,3] and k = 2 17 | Output: 3.00 18 | Explanation: 19 | Maximum average is (3+3)/2 = 6/2 = 3.00 20 | 21 | 22 | 注意事项 23 | 1 <= k <= n <= 30,000. 24 | 给定数组的元素范围是[-10,000, 10,000]。 25 | */ 26 | // 测试平台: https://www.lintcode.com/problem/maximum-average-subarray/ 27 | 28 | public class Solution { 29 | public double findMaxAverage(int[] A, int k) { 30 | final int N = A == null ? 0 : A.length; 31 | // 本质上就是滑动窗口 32 | double ans = 0; 33 | double s = 0; 34 | 35 | for (int i = 0; i < N; i++) { 36 | s += A[i]; 37 | if (i < k - 1) { 38 | continue; 39 | } 40 | double tmp = s / (double)k; 41 | ans = Math.max(ans, tmp); 42 | 43 | // 当前区间为[i + 1 - k, i + 1) 44 | // 那么将要滑出窗口的元素为A[i + 1 - k] 45 | // 这个时需,需要从滑动窗口的和里面减去这个元素 46 | s -= A[i + 1 - k]; 47 | } 48 | return ans; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /09.BinarySearch/868._子数组的最大平均值.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | 868. 子数组的最大平均值 5 | 中文 6 | English 7 | 给定一个由n个整数组成的数组,找到给定长度k的连续子数组,该子数组具有最大平均值。你需要输出最大平均值。 8 | 9 | 样例 10 | Example1 11 | 12 | Input: nums = [1,12,-5,-6,50,3] and k = 4 13 | Output: 12.75 14 | Explanation: 15 | Maximum average is (12-5-6+50)/4 = 51/4 = 12.75 16 | Example2 17 | 18 | Input: nums = [4,2,1,3,3] and k = 2 19 | Output: 3.00 20 | Explanation: 21 | Maximum average is (3+3)/2 = 6/2 = 3.00 22 | 注意事项 23 | 1 <= k <= n <= 30,000. 24 | 给定数组的元素范围是[-10,000, 10,000]。 25 | 26 | https://www.lintcode.com/problem/maximum-average-subarray/ 27 | """ 28 | 29 | class Solution: 30 | def findMaxAverage(self, A, k): 31 | N = 0 if not A else len(A) 32 | 33 | s = 0 34 | ans = 0 35 | 36 | for i in range(0, N): 37 | s += A[i] 38 | 39 | if i < k - 1: 40 | continue 41 | 42 | tmp = s / float(k) 43 | ans = max(ans, tmp) 44 | 45 | # 现在处理的区间是[i + 1 - k, i + 1) 46 | # 窗口滑动时,现在A[i + 1 - k]元素要扔掉了 47 | # 所以应该把A[i + 1 - k]从s里面减掉 48 | s -= A[i + 1 - k] 49 | 50 | return ans 51 | -------------------------------------------------------------------------------- /09.BinarySearch/BinarySearch.java: -------------------------------------------------------------------------------- 1 | public class BinarySearch { 2 | private boolean binarySearch(int[] A, int target) { 3 | bool binary_search(int[] A, int target) { 4 | if (A == null || A.length == 0) { 5 | return false; 6 | } 7 | int l = 0, r = A.length; 8 | while (l < r) { 9 | final int m = l + ((r - l) >> 1); 10 | if (A[m] == target) { 11 | return true; 12 | } 13 | if (A[m] < target) { 14 | l = m + 1; 15 | } else { 16 | r = m; 17 | } 18 | } 19 | return false; 20 | } 21 | } 22 | public static void main(String[] args) {} 23 | } 24 | -------------------------------------------------------------------------------- /09.BinarySearch/T1560.2.cpp: -------------------------------------------------------------------------------- 1 | // https://nanti.jisuanke.com/t/T1560 2 | // 出错点:注意一定要使用long long类型,或者int64_t类型 3 | // 出错点:给定的数组不是有序的 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | int64_t A[1000080]; 10 | 11 | int lower_bound(int64_t *A, int n, int64_t target) { 12 | int l = 0, r = n; 13 | while (l < r) { 14 | const int m = l + ((r - l) >> 1); 15 | if (A[m] < target) { 16 | l = m + 1; 17 | } else { 18 | r = m; 19 | } 20 | } 21 | return l; 22 | } 23 | 24 | bool binary_search(int64_t *A, int n, int64_t target) { 25 | int l = lower_bound(A, n, target); 26 | return l < n && A[l] == target; 27 | } 28 | 29 | int main(void) { 30 | int n, m; 31 | int64_t x; 32 | while (scanf("%d%d", &n, &m) != EOF) { 33 | for (int i = 0; i < n; i++) 34 | scanf("%lld", A + i); 35 | std::sort(A, A + n); 36 | for (int i = 0; i < m; i++) { 37 | scanf("%lld", &x); 38 | printf("%s\n", binary_search(A, n, x) ? "YES" : "NO"); 39 | } 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /09.BinarySearch/T1560.2.java: -------------------------------------------------------------------------------- 1 | // 测试平台: https://nanti.jisuanke.com/t/T1560 2 | import java.io.*; 3 | import java.util.*; 4 | 5 | public class Main { 6 | static private int lowerBound(long[] A, int n, long target) { 7 | int l = 0, r = n; 8 | while (l < r) { 9 | final int m = l + ((r - l) >> 1); 10 | if (A[m] < target) { 11 | l = m + 1; 12 | } else { 13 | r = m; 14 | } 15 | } 16 | return l; 17 | } 18 | 19 | static private boolean binarySearch(long[] A, int n, long target) { 20 | int l = lowerBound(A, n, target); 21 | return l < n && A[l] == target; 22 | } 23 | 24 | public static void main(String args[]) throws Exception { 25 | Scanner sc = new Scanner(System.in); 26 | int n = sc.nextInt(); 27 | int m = sc.nextInt(); 28 | long[] A = new long[n]; 29 | 30 | for (int i = 0; i < n; i++) { 31 | A[i] = sc.nextLong(); 32 | } 33 | Arrays.sort(A); 34 | for (int i = 0; i < m; i++) { 35 | long target = sc.nextLong(); 36 | System.out.println(binarySearch(A, n, target) ? "YES" : "NO"); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /09.BinarySearch/T1560.2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # 测试平台: https://nanti.jisuanke.com/t/T1560 4 | 5 | def lowerBound(A, target): 6 | l = 0 7 | r = len(A) if A else 0 8 | while l < r: 9 | m = l + ((r-l)>>1) 10 | if (A[m] < target): 11 | l = m + 1 12 | else: 13 | r = m 14 | return l 15 | 16 | def binarySearch(A, target): 17 | l = lowerBound(A, target) 18 | return True if l < len(A) and A[l] == target else False 19 | 20 | s = raw_input().split() 21 | n = int(s[0]) 22 | m = int(s[1]) 23 | s = raw_input().split() 24 | A = [int(x) for x in s] 25 | A.sort() 26 | 27 | for i in range(0, m): 28 | x = int(raw_input()) 29 | print "%s" % ("YES" if binarySearch(A, x) else "NO") 30 | 31 | 32 | -------------------------------------------------------------------------------- /09.BinarySearch/T1560.cpp: -------------------------------------------------------------------------------- 1 | // https://nanti.jisuanke.com/t/T1560 2 | // 出错点:注意一定要使用long long类型,或者int64_t类型 3 | // 出错点:给定的数组不是有序的 4 | #include 5 | #include 6 | #include 7 | 8 | int64_t A[1000080]; 9 | 10 | bool binary_search(int64_t *A, int n, int64_t target) { 11 | int l = 0, r = n; 12 | while (l < r) { 13 | const int m = l + ((r - l) >> 1); 14 | if (A[m] == target) { 15 | return true; 16 | } 17 | if (A[m] < target) { 18 | l = m + 1; 19 | } else { 20 | r = m; 21 | } 22 | } 23 | return false; 24 | } 25 | 26 | int main(void) { 27 | int n, m; 28 | int64_t x; 29 | while (scanf("%d%d", &n, &m) != EOF) { 30 | for (int i = 0; i < n; i++) 31 | scanf("%lld", A + i); 32 | std::sort(A, A + n); 33 | for (int i = 0; i < m; i++) { 34 | scanf("%lld", &x); 35 | printf("%s\n", binary_search(A, n, x) ? "YES" : "NO"); 36 | } 37 | } 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /09.BinarySearch/T1560.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # 测试平台: https://nanti.jisuanke.com/t/T1560 4 | 5 | def binarySearch(A, target): 6 | l = 0 7 | r = len(A) if A else 0 8 | 9 | while l < r: 10 | m = l + ((r-l)>>1) 11 | if (A[m] == target): 12 | return True 13 | elif (A[m] < target): 14 | l = m + 1 15 | else: 16 | r = m 17 | 18 | return False 19 | 20 | s = raw_input().split() 21 | n = int(s[0]) 22 | m = int(s[1]) 23 | s = raw_input().split() 24 | A = [int(x) for x in s] 25 | A.sort() 26 | 27 | for i in range(0, m): 28 | x = int(raw_input()) 29 | print "%s" % ("YES" if binarySearch(A, x) else "NO") 30 | 31 | 32 | -------------------------------------------------------------------------------- /09.BinarySearch/T1562.cpp: -------------------------------------------------------------------------------- 1 | // https://nanti.jisuanke.com/t/T1562 2 | // 出错点:注意一定要使用long long类型,或者int64_t类型 3 | // 出错点:给定的数组不是有序的 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | int64_t A[1000080]; 10 | 11 | int upper_bound(int64_t *A, int n, int64_t target) { 12 | int l = 0, r = n; 13 | while (l < r) { 14 | const int m = l + ((r - l) >> 1); 15 | if (A[m] <= target) { 16 | l = m + 1; 17 | } else { 18 | r = m; 19 | } 20 | } 21 | return l; 22 | } 23 | 24 | int main(void) { 25 | int n, m; 26 | int64_t x; 27 | while (scanf("%d%d", &n, &m) != EOF) { 28 | for (int i = 0; i < n; i++) 29 | scanf("%lld", A + i); 30 | std::sort(A, A + n); 31 | for (int i = 0; i < m; i++) { 32 | scanf("%lld", &x); 33 | auto idx = upper_bound(A, n, x); 34 | printf("%lld\n", idx == n ? -1 : A[idx]); 35 | } 36 | } 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /09.BinarySearch/T1562.java: -------------------------------------------------------------------------------- 1 | // 测试平台: https://nanti.jisuanke.com/t/T1562 2 | import java.io.*; 3 | import java.util.*; 4 | 5 | public class Main { 6 | static private int upperBound(long[] A, int n, long target) { 7 | int l = 0, r = n; 8 | while (l < r) { 9 | final int m = l + ((r - l) >> 1); 10 | if (A[m] <= target) { 11 | l = m + 1; 12 | } else { 13 | r = m; 14 | } 15 | } 16 | return l; 17 | } 18 | 19 | public static void main(String args[]) throws Exception { 20 | Scanner sc = new Scanner(System.in); 21 | int n = sc.nextInt(); 22 | int m = sc.nextInt(); 23 | long[] A = new long[n]; 24 | 25 | for (int i = 0; i < n; i++) { 26 | A[i] = sc.nextLong(); 27 | } 28 | Arrays.sort(A); 29 | for (int i = 0; i < m; i++) { 30 | long target = sc.nextLong(); 31 | int idx = upperBound(A, A.length, target); 32 | System.out.println(idx == A.length ? -1 : A[idx]); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /09.BinarySearch/T1562.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # 测试平台: https://nanti.jisuanke.com/t/T1562 4 | 5 | def upperBound(A, target): 6 | l = 0 7 | r = len(A) if A else 0 8 | while l < r: 9 | m = l + ((r-l)>>1) 10 | if (A[m] <= target): 11 | l = m + 1 12 | else: 13 | r = m 14 | return l 15 | 16 | s = raw_input().split() 17 | n = int(s[0]) 18 | m = int(s[1]) 19 | s = raw_input().split() 20 | A = [int(x) for x in s] 21 | A.sort() 22 | 23 | for i in range(0, m): 24 | x = int(raw_input()) 25 | idx = upperBound(A, x) 26 | print '%s' % (-1 if idx >= len(A) else A[idx]) 27 | 28 | 29 | -------------------------------------------------------------------------------- /10.DoublePointer/209.长度最小的子数组.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=209 lang=cpp 3 | * 4 | * [209] 长度最小的子数组 5 | * 6 | * https://leetcode-cn.com/problems/minimum-size-subarray-sum/description/ 7 | * 8 | * algorithms 9 | * Medium (44.84%) 10 | * Likes: 539 11 | * Dislikes: 0 12 | * Total Accepted: 110.2K 13 | * Total Submissions: 245.9K 14 | * Testcase Example: '7\n[2,3,1,2,4,3]' 15 | * 16 | * 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 17 | * 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。 18 | * 19 | * 20 | * 21 | * 示例: 22 | * 23 | * 输入:s = 7, nums = [2,3,1,2,4,3] 24 | * 输出:2 25 | * 解释:子数组 [4,3] 是该条件下的长度最小的子数组。 26 | * 27 | * 28 | * 29 | * 30 | * 进阶: 31 | * 32 | * 33 | * 如果你已经完成了 O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。 34 | * 35 | * 36 | */ 37 | 38 | // @lc code=start 39 | class Solution { 40 | public: 41 | int minSubArrayLen(int s, vector& A) { 42 | const int N = A.size(); 43 | int left = -1; 44 | uint64_t sum = 0; 45 | int ans = N + N; 46 | for (int i = 0; i < N; i++) { 47 | sum += A[i]; 48 | while (left < i && sum >= s) { 49 | ans = min(ans, i - left); 50 | sum -= A[++left]; 51 | } 52 | } 53 | return ans > N ? 0 : ans; 54 | } 55 | }; 56 | // @lc code=end 57 | -------------------------------------------------------------------------------- /10.DoublePointer/209.长度最小的子数组.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=209 lang=java 3 | * 4 | * [209] 长度最小的子数组 5 | * 6 | * https://leetcode-cn.com/problems/minimum-size-subarray-sum/description/ 7 | * 8 | * algorithms 9 | * Medium (44.84%) 10 | * Likes: 539 11 | * Dislikes: 0 12 | * Total Accepted: 110.2K 13 | * Total Submissions: 245.9K 14 | * Testcase Example: '7\n[2,3,1,2,4,3]' 15 | * 16 | * 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 17 | * 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。 18 | * 19 | * 20 | * 21 | * 示例: 22 | * 23 | * 输入:s = 7, nums = [2,3,1,2,4,3] 24 | * 输出:2 25 | * 解释:子数组 [4,3] 是该条件下的长度最小的子数组。 26 | * 27 | * 28 | * 29 | * 30 | * 进阶: 31 | * 32 | * 33 | * 如果你已经完成了 O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。 34 | * 35 | * 36 | */ 37 | 38 | // @lc code=start 39 | class Solution { 40 | public int minSubArrayLen(int T, int[] A) { 41 | final int N = A == null ? 0 : A.length; 42 | int left = -1; 43 | int ans = N + 1; 44 | long s = 0; 45 | for (int i = 0; i < N; i++) { 46 | s += A[i]; 47 | while (s >= T) { 48 | ans = Math.min(ans, i - left); 49 | s -= A[++left]; 50 | } 51 | } 52 | return ans > N ? 0 : ans; 53 | } 54 | } 55 | // @lc code=end -------------------------------------------------------------------------------- /10.DoublePointer/209.长度最小的子数组.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=209 lang=python 3 | # 4 | # [209] 长度最小的子数组 5 | # 6 | # https://leetcode-cn.com/problems/minimum-size-subarray-sum/description/ 7 | # 8 | # algorithms 9 | # Medium (44.84%) 10 | # Likes: 539 11 | # Dislikes: 0 12 | # Total Accepted: 110.2K 13 | # Total Submissions: 245.9K 14 | # Testcase Example: '7\n[2,3,1,2,4,3]' 15 | # 16 | # 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 17 | # 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。 18 | # 19 | # 20 | # 21 | # 示例: 22 | # 23 | # 输入:s = 7, nums = [2,3,1,2,4,3] 24 | # 输出:2 25 | # 解释:子数组 [4,3] 是该条件下的长度最小的子数组。 26 | # 27 | # 28 | # 29 | # 30 | # 进阶: 31 | # 32 | # 33 | # 如果你已经完成了 O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。 34 | # 35 | # 36 | # 37 | 38 | # @lc code=start 39 | class Solution(object): 40 | def minSubArrayLen(self, s, A): 41 | N = 0 if not A else len(A) 42 | left = -1 43 | sum = 0 44 | ans = -1 45 | for i in range(N): 46 | sum += A[i] 47 | while left < i and sum >= s: 48 | if ans == -1 or ans > i - left: 49 | ans = i - left 50 | left += 1 51 | sum -= A[left] 52 | 53 | return max(ans, 0) 54 | 55 | # @lc code=end 56 | 57 | -------------------------------------------------------------------------------- /10.DoublePointer/386.最多有k个不同字符的最长子字符串.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 给定字符串S,找到最多有k个不同字符的最长子串T。 3 | 4 | 样例 5 | 样例 1: 6 | 7 | 输入: S = "eceba" 并且 k = 3 8 | 输出: 4 9 | 解释: T = "eceb" 10 | 样例 2: 11 | 12 | 输入: S = "WORLD" 并且 k = 4 13 | 输出: 4 14 | 解释: T = "WORL" 或 "ORLD" 15 | 挑战 16 | O(n) 时间复杂度 17 | 18 | https://www.lintcode.com/problem/386/ 19 | */ 20 | 21 | class Solution { 22 | public: 23 | /** 24 | * @param s: A string 25 | * @param k: An integer 26 | * @return: An integer 27 | */ 28 | int lengthOfLongestSubstringKDistinct(string &s, int k) { 29 | // write your code here 30 | const int N = s.length(); 31 | int left = -1; 32 | int ans = 0; 33 | 34 | int H[256] = {}; 35 | int cnt = 0; 36 | 37 | for (int i = 0; i < N; i++) { 38 | const char c = s[i]; 39 | 40 | cnt += H[c] == 0; 41 | H[c]++; 42 | 43 | while (left < i && cnt > k) { 44 | const char x = s[++left]; 45 | if (H[x] == 1) { 46 | cnt--; 47 | } 48 | H[x]--; 49 | } 50 | 51 | ans = max(ans, i - left); 52 | } 53 | return ans; 54 | } 55 | }; -------------------------------------------------------------------------------- /10.DoublePointer/386.最多有k个不同字符的最长子字符串.java: -------------------------------------------------------------------------------- 1 | /* 2 | 给定字符串S,找到最多有k个不同字符的最长子串T。 3 | 4 | 样例 5 | 样例 1: 6 | 7 | 输入: S = "eceba" 并且 k = 3 8 | 输出: 4 9 | 解释: T = "eceb" 10 | 样例 2: 11 | 12 | 输入: S = "WORLD" 并且 k = 4 13 | 输出: 4 14 | 解释: T = "WORL" 或 "ORLD" 15 | 挑战 16 | O(n) 时间复杂度 17 | 18 | https://www.lintcode.com/problem/386/ 19 | */ 20 | 21 | 22 | class Counter extends HashMap { 23 | public int get(Character k) { 24 | return containsKey(k) ? super.get(k) : 0; 25 | } 26 | 27 | public void add(Character k, int v) { 28 | put(k, get(k) + v); 29 | if (get(k) <= 0) { 30 | remove(k); 31 | } 32 | } 33 | } 34 | public class Solution { 35 | public int lengthOfLongestSubstringKDistinct(String s, int k) { 36 | // write your code here 37 | final int N = s == null ? 0 : s.length(); 38 | int left = -1; 39 | int ans = 0; 40 | 41 | Counter H = new Counter(); 42 | 43 | for (int i = 0; i < N; i++) { 44 | H.add(s.charAt(i), 1); 45 | 46 | while (H.size() > k) { 47 | Character c = s.charAt(++left); 48 | H.add(c, -1); 49 | } 50 | 51 | ans = Math.max(ans, i - left); 52 | } 53 | return ans; 54 | } 55 | } 56 | 57 | 58 | -------------------------------------------------------------------------------- /10.DoublePointer/386.最多有k个不同字符的最长子字符串.py: -------------------------------------------------------------------------------- 1 | # /* 2 | # 给定字符串S,找到最多有k个不同字符的最长子串T。 3 | # 4 | # 样例 5 | # 样例 1: 6 | # 7 | # 输入: S = "eceba" 并且 k = 3 8 | # 输出: 4 9 | # 解释: T = "eceb" 10 | # 样例 2: 11 | # 12 | # 输入: S = "WORLD" 并且 k = 4 13 | # 输出: 4 14 | # 解释: T = "WORL" 或 "ORLD" 15 | # 挑战 16 | # O(n) 时间复杂度 17 | # 18 | # https://www.lintcode.com/problem/386/ 19 | # */ 20 | 21 | class Solution: 22 | """ 23 | @param s: A string 24 | @param k: An integer 25 | @return: An integer 26 | """ 27 | def lengthOfLongestSubstringKDistinct(self, s, k): 28 | # write your code here 29 | N = 0 if not s else len(s) 30 | left = -1 31 | ans = 0 32 | cnt = 0 33 | H = [0] * 256 34 | 35 | for i in range(N): 36 | c = ord(s[i]) 37 | if H[c] == 0: 38 | cnt += 1 39 | H[c]+= 1 40 | 41 | while left < i and cnt > k: 42 | left += 1 43 | c = ord(s[left]) 44 | 45 | if H[c] == 1: 46 | cnt -= 1 47 | H[c] -= 1 48 | 49 | ans = max(ans, i - left) 50 | 51 | return ans -------------------------------------------------------------------------------- /10.DoublePointer/53.最大子序和.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=53 lang=cpp 3 | * 4 | * [53] 最大子序和 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | // @lc code=start 11 | class Solution { 12 | public: 13 | int maxSubArray(vector& A) { 14 | const int N = A.size(); 15 | if (N <= 0) { 16 | return 0; 17 | } 18 | 19 | int left = -1; 20 | int s = 0; 21 | int ans = INT_MIN; 22 | 23 | int max_item = *max_element(A.begin(), A.end()); 24 | if (max_item < 0) { 25 | return max_item; 26 | } 27 | 28 | for (int i = 0; i < N; i++) { 29 | // 将A[i]添加到区间中 30 | s += A[i]; 31 | 32 | // 如果当前的区间的状态被破坏了 33 | if (s <= 0) { 34 | // 直接把当前区间扔掉 35 | left = i; 36 | s = 0; 37 | } 38 | 39 | // 现在的区间是以A[i]为右端点能够取得的最大 40 | // 值 41 | ans = max(ans, s); 42 | } 43 | 44 | return ans; 45 | } 46 | }; 47 | // @lc code=end 48 | -------------------------------------------------------------------------------- /10.DoublePointer/64.字符流中第一个只出现一次的字符.cpp: -------------------------------------------------------------------------------- 1 | // 64. 字符流中第一个只出现一次的字符 2 | /* 3 | 请实现一个函数用来找出字符流中第一个只出现一次的字符。 4 | 5 | 例如,当从字符流中只读出前两个字符”go”时,第一个只出现一次的字符是’g’。 6 | 7 | 当从该字符流中读出前六个字符”google”时,第一个只出现一次的字符是’l’。 8 | 9 | 如果当前字符流没有存在出现一次的字符,返回#字符。 10 | 11 | 输入:"google" 12 | 13 | 输出:"ggg#ll" 14 | 15 | 解释:每当字符流读入一个字符,就进行一次判断并输出当前的第一个只出现一次的字符。 16 | 17 | */ 18 | // https://www.acwing.com/problem/content/60/ 19 | 20 | class Solution{ 21 | int left = -1; 22 | int i = -1; 23 | int cnt[256] = {}; 24 | string s; 25 | public: 26 | //Insert one char from stringstream 27 | void insert(char ch){ 28 | i++; 29 | s.push_back(ch); 30 | cnt[ch]++; 31 | while (left < i && cnt[s[1+left]] > 1) { 32 | ++left; 33 | } 34 | } 35 | //return the first appearence once char in current stringstream 36 | char firstAppearingOnce(){ 37 | if (left >= i) { 38 | return '#'; 39 | } 40 | return s[left+1]; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /10.DoublePointer/64.字符流中第一个只出现一次的字符.java: -------------------------------------------------------------------------------- 1 | // 64. 字符流中第一个只出现一次的字符 2 | /* 3 | 请实现一个函数用来找出字符流中第一个只出现一次的字符。 4 | 5 | 例如,当从字符流中只读出前两个字符”go”时,第一个只出现一次的字符是’g’。 6 | 7 | 当从该字符流中读出前六个字符”google”时,第一个只出现一次的字符是’l’。 8 | 9 | 如果当前字符流没有存在出现一次的字符,返回#字符。 10 | 11 | 输入:"google" 12 | 13 | 输出:"ggg#ll" 14 | 15 | 解释:每当字符流读入一个字符,就进行一次判断并输出当前的第一个只出现一次的字符。 16 | 17 | */ 18 | // https://www.acwing.com/problem/content/60/ 19 | class Solution { 20 | private String s = new String(); 21 | private int left = -1; 22 | private int[] cnt = new int[256]; 23 | private int i = -1; 24 | //Insert one char from stringstream 25 | public void insert(char ch){ 26 | i++; 27 | s += ch; 28 | cnt[(int)ch]++; 29 | while (left < i && cnt[(int)s.charAt(1+left)] > 1) { 30 | ++left; 31 | } 32 | } 33 | //return the first appearence once char in current stringstream 34 | public char firstAppearingOnce(){ 35 | if (left >= i) { 36 | return '#'; 37 | } 38 | return s.charAt(left+1); 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /10.DoublePointer/64.字符流中第一个只出现一次的字符.py: -------------------------------------------------------------------------------- 1 | # // 64. 字符流中第一个只出现一次的字符 2 | # /* 3 | # 请实现一个函数用来找出字符流中第一个只出现一次的字符。 4 | # 5 | # 例如,当从字符流中只读出前两个字符”go”时,第一个只出现一次的字符是’g’。 6 | # 7 | # 当从该字符流中读出前六个字符”google”时,第一个只出现一次的字符是’l’。 8 | # 9 | # 如果当前字符流没有存在出现一次的字符,返回#字符。 10 | # 11 | # 输入:"google" 12 | # 13 | # 输出:"ggg#ll" 14 | # 解释:每当字符流读入一个字符,就进行一次判断并输出当前的第一个只出现一次的字符。 15 | # 16 | # */ 17 | # // https://www.acwing.com/problem/content/60/ 18 | 19 | 20 | class Solution: 21 | def __init__(self): 22 | self.s = "" 23 | self.left = -1 24 | self.cnt = [0]*256 25 | self.i = -1 26 | 27 | def insert(self, char): 28 | """ 29 | :type char: str 30 | :rtype: void 31 | """ 32 | self.i += 1 33 | self.s += char 34 | self.cnt[ord(char)] += 1 35 | while self.left < self.i and self.cnt[ord(self.s[1 + self.left])] > 1: 36 | self.left += 1 37 | 38 | def firstAppearingOnce(self): 39 | """ 40 | :rtype: str 41 | """ 42 | if self.left >= self.i: 43 | return '#' 44 | return self.s[self.left+1] -------------------------------------------------------------------------------- /10.DoublePointer/713.乘积小于k的子数组.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=713 lang=cpp 3 | * 4 | * [713] 乘积小于K的子数组 5 | * 6 | * https://leetcode-cn.com/problems/subarray-product-less-than-k/description/ 7 | * 8 | * algorithms 9 | * Medium (37.56%) 10 | * Likes: 224 11 | * Dislikes: 0 12 | * Total Accepted: 12.1K 13 | * Total Submissions: 32.2K 14 | * Testcase Example: '[10,5,2,6]\n100' 15 | * 16 | * 给定一个正整数数组 nums。 17 | * 18 | * 找出该数组内乘积小于 k 的连续的子数组的个数。 19 | * 20 | * 示例 1: 21 | * 22 | * 23 | * 输入: nums = [10,5,2,6], k = 100 24 | * 输出: 8 25 | * 解释: 8个乘积小于100的子数组分别为: [10], [5], [2], [6], [10,5], [5,2], 26 | * [2,6], [5,2,6]。 需要注意的是 [10,5,2] 并不是乘积小于100的子数组。 27 | * 28 | * 29 | * 说明: 30 | * 31 | * 32 | * 0 < nums.length <= 50000 33 | * 0 < nums[i] < 1000 34 | * 0 <= k < 10^6 35 | * 36 | * 37 | */ 38 | 39 | // @lc code=start 40 | class Solution { 41 | public: 42 | int numSubarrayProductLessThanK(vector& A, int k) { 43 | const int N = A.size(); 44 | 45 | int left = -1; 46 | uint64_t s = 1; 47 | int ans = 0; 48 | for (int i = 0; i < N; i++) { 49 | const uint64_t x = A[i]; 50 | s *= x; 51 | 52 | // 坏了才移动 53 | while (s >= k && left < i) { 54 | s /= A[++left]; 55 | } 56 | 57 | // 计算子数组的长度 58 | const int len = i - left; 59 | // 那么以x 为右端点的区间的个数就是 60 | ans += len; 61 | } 62 | 63 | return ans; 64 | } 65 | }; 66 | // @lc code=end 67 | -------------------------------------------------------------------------------- /10.DoublePointer/921.最长子数组和为k.java: -------------------------------------------------------------------------------- 1 | /* 2 | 911. 最大子数组之和为k 3 | 中文 4 | English 5 | 给一个数组nums和目标值k,找到数组中最长的子数组,使其中的元素和为k。如果没有,则返回0。 6 | 7 | 样例 8 | Example1 9 | 10 | Input: nums = [1, -1, 5, -2, 3], k = 3 11 | Output: 4 12 | Explanation: 13 | because the subarray [1, -1, 5, -2] sums to 3 and is the longest. 14 | Example2 15 | 16 | Input: nums = [-2, -1, 2, 1], k = 1 17 | Output: 2 18 | Explanation: 19 | because the subarray [-1, 2] sums to 1 and is the longest. 20 | 挑战 21 | 能否用O(n)的时间复杂度完成? 22 | 23 | 注意事项 24 | 数组之和保证在32位有符号整型数的范围内 25 | */ 26 | 27 | // 测试链接: https://www.lintcode.com/problem/maximum-size-subarray-sum-equals-k/leaderboard/ 28 | 29 | public class Solution { 30 | /** 31 | * @param nums: an array 32 | * @param k: a target value 33 | * @return: the maximum length of a subarray that sums to k 34 | */ 35 | public int maxSubArrayLen(int[] A, int k) { 36 | final int N = A == null ? 0 : A.length; 37 | Map H = new HashMap<>(); 38 | Long s = Long.valueOf(0); 39 | int ans = 0; 40 | H.put(s, -1); 41 | for (int i = 0; i < N; i++) { 42 | s += A[i]; 43 | Long want = Long.valueOf(s - k); 44 | int wantPos = H.getOrDefault(want, N + 1); 45 | ans = Math.max(ans, i - wantPos); 46 | // 如果已经存在了 47 | if (!H.containsKey(s)) { 48 | H.put(s, i); 49 | } 50 | } 51 | return ans; 52 | } 53 | } 54 | 55 | 56 | -------------------------------------------------------------------------------- /10.DoublePointer/921.最长子数组和为k.py: -------------------------------------------------------------------------------- 1 | # /* 2 | # 911. 最大子数组之和为k 3 | # 中文 4 | # English 5 | # 给一个数组nums和目标值k,找到数组中最长的子数组,使其中的元素和为k。如果没有,则返回0。 6 | # 7 | # 样例 8 | # Example1 9 | # 10 | # Input: nums = [1, -1, 5, -2, 3], k = 3 11 | # Output: 4 12 | # Explanation: 13 | # because the subarray [1, -1, 5, -2] sums to 3 and is the longest. 14 | # Example2 15 | # 16 | # Input: nums = [-2, -1, 2, 1], k = 1 17 | # Output: 2 18 | # Explanation: 19 | # because the subarray [-1, 2] sums to 1 and is the longest. 20 | # 挑战 21 | # 能否用O(n)的时间复杂度完成? 22 | # 23 | # 注意事项 24 | # 数组之和保证在32位有符号整型数的范围内 25 | # */ 26 | # 27 | # // 测试链接: https://www.lintcode.com/problem/maximum-size-subarray-sum-equals-k/leaderboard/ 28 | 29 | class Solution: 30 | """ 31 | @param nums: an array 32 | @param k: a target value 33 | @return: the maximum length of a subarray that sums to k 34 | """ 35 | def maxSubArrayLen(self, A, k): 36 | # Write your code here 37 | N = 0 if not A else len(A) 38 | ans = 0 39 | 40 | H = {} 41 | H[0] = -1 42 | 43 | pre = 0 44 | for i in range(N): 45 | pre += A[i] 46 | want = pre - k 47 | 48 | pos = H.get(want, N + N) 49 | ans = max(ans, i - pos) 50 | 51 | if -2 == H.get(pre, -2): 52 | H[pre] = i 53 | 54 | return ans 55 | -------------------------------------------------------------------------------- /11.Greedy/11.盛最多水的容器.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=11 lang=cpp 3 | * 4 | * [11] 盛最多水的容器 5 | * 6 | * https://leetcode-cn.com/problems/container-with-most-water/description/ 7 | * 8 | * algorithms 9 | * Medium (64.78%) 10 | * Likes: 2242 11 | * Dislikes: 0 12 | * Total Accepted: 377.9K 13 | * Total Submissions: 583.5K 14 | * Testcase Example: '[1,8,6,2,5,4,8,3,7]' 15 | * 16 | * 给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 17 | * (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 18 | * 19 | * 说明:你不能倾斜容器。 20 | * 21 | * 22 | * 23 | * 示例 1: 24 | * 25 | * 26 | * 27 | * 28 | * 输入:[1,8,6,2,5,4,8,3,7] 29 | * 输出:49 30 | * 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。 31 | * 32 | * 示例 2: 33 | * 34 | * 35 | * 输入:height = [1,1] 36 | * 输出:1 37 | * 38 | * 39 | * 示例 3: 40 | * 41 | * 42 | * 输入:height = [4,3,2,1,4] 43 | * 输出:16 44 | * 45 | * 46 | * 示例 4: 47 | * 48 | * 49 | * 输入:height = [1,2,1] 50 | * 输出:2 51 | * 52 | * 53 | * 54 | * 55 | * 提示: 56 | * 57 | * 58 | * n = height.length 59 | * 2 60 | * 0 61 | * 62 | * 63 | */ 64 | 65 | // @lc code=start 66 | class Solution { 67 | public: 68 | int maxArea(vector& height) { 69 | 70 | } 71 | }; 72 | // @lc code=end 73 | 74 | -------------------------------------------------------------------------------- /11.Greedy/11.盛最多水的容器.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=11 lang=python 3 | # 4 | # [11] 盛最多水的容器 5 | # 6 | # https://leetcode-cn.com/problems/container-with-most-water/description/ 7 | # 8 | # algorithms 9 | # Medium (64.78%) 10 | # Likes: 2242 11 | # Dislikes: 0 12 | # Total Accepted: 377.9K 13 | # Total Submissions: 583.5K 14 | # Testcase Example: '[1,8,6,2,5,4,8,3,7]' 15 | # 16 | # 给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, 17 | # ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 18 | # 19 | # 说明:你不能倾斜容器。 20 | # 21 | # 22 | # 23 | # 示例 1: 24 | # 25 | # 26 | # 27 | # 28 | # 输入:[1,8,6,2,5,4,8,3,7] 29 | # 输出:49 30 | # 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。 31 | # 32 | # 示例 2: 33 | # 34 | # 35 | # 输入:height = [1,1] 36 | # 输出:1 37 | # 38 | # 39 | # 示例 3: 40 | # 41 | # 42 | # 输入:height = [4,3,2,1,4] 43 | # 输出:16 44 | # 45 | # 46 | # 示例 4: 47 | # 48 | # 49 | # 输入:height = [1,2,1] 50 | # 输出:2 51 | # 52 | # 53 | # 54 | # 55 | # 提示: 56 | # 57 | # 58 | # n = height.length 59 | # 2 60 | # 0 61 | # 62 | # 63 | # 64 | 65 | # @lc code=start 66 | class Solution(object): 67 | def maxArea(self, height): 68 | """ 69 | :type height: List[int] 70 | :rtype: int 71 | """ 72 | # @lc code=end 73 | 74 | -------------------------------------------------------------------------------- /11.Greedy/42.接雨水.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=42 lang=cpp 3 | * 4 | * [42] 接雨水 5 | * 6 | * https://leetcode-cn.com/problems/trapping-rain-water/description/ 7 | * 8 | * algorithms 9 | * Hard (54.56%) 10 | * Likes: 2115 11 | * Dislikes: 0 12 | * Total Accepted: 205K 13 | * Total Submissions: 375.4K 14 | * Testcase Example: '[0,1,0,2,1,0,1,3,2,1,2,1]' 15 | * 16 | * 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 17 | * 18 | * 19 | * 20 | * 示例 1: 21 | * 22 | * 23 | * 24 | * 25 | * 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 26 | * 输出:6 27 | * 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 28 | * 29 | * 30 | * 示例 2: 31 | * 32 | * 33 | * 输入:height = [4,2,0,3,2,5] 34 | * 输出:9 35 | * 36 | * 37 | * 38 | * 39 | * 提示: 40 | * 41 | * 42 | * n == height.length 43 | * 0 44 | * 0 45 | * 46 | * 47 | */ 48 | 49 | // @lc code=start 50 | class Solution { 51 | public: 52 | int trap(vector& height) { 53 | 54 | } 55 | }; 56 | // @lc code=end 57 | 58 | -------------------------------------------------------------------------------- /11.Greedy/42.接雨水.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=42 lang=java 3 | * 4 | * [42] 接雨水 5 | * 6 | * https://leetcode-cn.com/problems/trapping-rain-water/description/ 7 | * 8 | * algorithms 9 | * Hard (54.56%) 10 | * Likes: 2115 11 | * Dislikes: 0 12 | * Total Accepted: 205K 13 | * Total Submissions: 375.4K 14 | * Testcase Example: '[0,1,0,2,1,0,1,3,2,1,2,1]' 15 | * 16 | * 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 17 | * 18 | * 19 | * 20 | * 示例 1: 21 | * 22 | * 23 | * 24 | * 25 | * 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 26 | * 输出:6 27 | * 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 28 | * 29 | * 30 | * 示例 2: 31 | * 32 | * 33 | * 输入:height = [4,2,0,3,2,5] 34 | * 输出:9 35 | * 36 | * 37 | * 38 | * 39 | * 提示: 40 | * 41 | * 42 | * n == height.length 43 | * 0 44 | * 0 45 | * 46 | * 47 | */ 48 | 49 | // @lc code=start 50 | class Solution { 51 | public int trap(int[] height) { 52 | 53 | } 54 | } 55 | // @lc code=end 56 | 57 | -------------------------------------------------------------------------------- /11.Greedy/42.接雨水.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=42 lang=python 3 | # 4 | # [42] 接雨水 5 | # 6 | # https://leetcode-cn.com/problems/trapping-rain-water/description/ 7 | # 8 | # algorithms 9 | # Hard (54.56%) 10 | # Likes: 2115 11 | # Dislikes: 0 12 | # Total Accepted: 205K 13 | # Total Submissions: 375.4K 14 | # Testcase Example: '[0,1,0,2,1,0,1,3,2,1,2,1]' 15 | # 16 | # 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 17 | # 18 | # 19 | # 20 | # 示例 1: 21 | # 22 | # 23 | # 24 | # 25 | # 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 26 | # 输出:6 27 | # 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 28 | # 29 | # 30 | # 示例 2: 31 | # 32 | # 33 | # 输入:height = [4,2,0,3,2,5] 34 | # 输出:9 35 | # 36 | # 37 | # 38 | # 39 | # 提示: 40 | # 41 | # 42 | # n == height.length 43 | # 0 44 | # 0 45 | # 46 | # 47 | # 48 | 49 | # @lc code=start 50 | class Solution(object): 51 | def trap(self, height): 52 | """ 53 | :type height: List[int] 54 | :rtype: int 55 | """ 56 | # @lc code=end 57 | 58 | -------------------------------------------------------------------------------- /11.Greedy/45.跳跃游戏-ii.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=45 lang=python 3 | # 4 | # [45] 跳跃游戏 II 5 | # 6 | # https://leetcode-cn.com/problems/jump-game-ii/description/ 7 | # 8 | # algorithms 9 | # Hard (38.45%) 10 | # Likes: 863 11 | # Dislikes: 0 12 | # Total Accepted: 108.6K 13 | # Total Submissions: 281.7K 14 | # Testcase Example: '[2,3,1,1,4]' 15 | # 16 | # 给定一个非负整数数组,你最初位于数组的第一个位置。 17 | # 18 | # 数组中的每个元素代表你在该位置可以跳跃的最大长度。 19 | # 20 | # 你的目标是使用最少的跳跃次数到达数组的最后一个位置。 21 | # 22 | # 示例: 23 | # 24 | # 输入: [2,3,1,1,4] 25 | # 输出: 2 26 | # 解释: 跳到最后一个位置的最小跳跃数是 2。 27 | # 从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。 28 | # 29 | # 30 | # 说明: 31 | # 32 | # 假设你总是可以到达数组的最后一个位置。 33 | # 34 | # 35 | 36 | # @lc code=start 37 | class Solution(object): 38 | def jump(self, A): 39 | N = 0 if not A else len(A) 40 | 41 | ans = 0 42 | i = 0 43 | 44 | while i < N and i + A[i] < N - 1: 45 | old = i + A[i] 46 | j = i + 1 47 | pos = old 48 | while j <= old: 49 | if j + A[j] > pos: 50 | i = j 51 | pos = j + A[j] 52 | j += 1 53 | 54 | if pos == old: 55 | return -1 56 | 57 | ans += 1 58 | 59 | return ans + (1 if (i < N - 1) else 0) 60 | # @lc code=end 61 | 62 | -------------------------------------------------------------------------------- /11.Greedy/763.划分字母区间.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=763 lang=cpp 3 | * 4 | * [763] 划分字母区间 5 | * 6 | * https://leetcode-cn.com/problems/partition-labels/description/ 7 | * 8 | * algorithms 9 | * Medium (76.62%) 10 | * Likes: 458 11 | * Dislikes: 0 12 | * Total Accepted: 58.5K 13 | * Total Submissions: 76.4K 14 | * Testcase Example: '"ababcbacadefegdehijhklij"' 15 | * 16 | * 字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。 17 | * 18 | * 19 | * 20 | * 示例: 21 | * 22 | * 23 | * 输入:S = "ababcbacadefegdehijhklij" 24 | * 输出:[9,7,8] 25 | * 解释: 26 | * 划分结果为 "ababcbaca", "defegde", "hijhklij"。 27 | * 每个字母最多出现在一个片段中。 28 | * 像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。 29 | * 30 | * 31 | * 32 | * 33 | * 提示: 34 | * 35 | * 36 | * S的长度在[1, 500]之间。 37 | * S只包含小写字母 'a' 到 'z' 。 38 | * 39 | * 40 | */ 41 | 42 | // @lc code=start 43 | class Solution { 44 | public: 45 | vector partitionLabels(string S) { 46 | 47 | } 48 | }; 49 | // @lc code=end 50 | 51 | -------------------------------------------------------------------------------- /11.Greedy/763.划分字母区间.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=763 lang=java 3 | * 4 | * [763] 划分字母区间 5 | * 6 | * https://leetcode-cn.com/problems/partition-labels/description/ 7 | * 8 | * algorithms 9 | * Medium (76.62%) 10 | * Likes: 458 11 | * Dislikes: 0 12 | * Total Accepted: 58.5K 13 | * Total Submissions: 76.4K 14 | * Testcase Example: '"ababcbacadefegdehijhklij"' 15 | * 16 | * 字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。 17 | * 18 | * 19 | * 20 | * 示例: 21 | * 22 | * 23 | * 输入:S = "ababcbacadefegdehijhklij" 24 | * 输出:[9,7,8] 25 | * 解释: 26 | * 划分结果为 "ababcbaca", "defegde", "hijhklij"。 27 | * 每个字母最多出现在一个片段中。 28 | * 像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。 29 | * 30 | * 31 | * 32 | * 33 | * 提示: 34 | * 35 | * 36 | * S的长度在[1, 500]之间。 37 | * S只包含小写字母 'a' 到 'z' 。 38 | * 39 | * 40 | */ 41 | 42 | // @lc code=start 43 | class Solution { 44 | public List partitionLabels(String S) { 45 | 46 | } 47 | } 48 | // @lc code=end 49 | 50 | -------------------------------------------------------------------------------- /11.Greedy/763.划分字母区间.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=763 lang=python 3 | # 4 | # [763] 划分字母区间 5 | # 6 | # https://leetcode-cn.com/problems/partition-labels/description/ 7 | # 8 | # algorithms 9 | # Medium (76.62%) 10 | # Likes: 458 11 | # Dislikes: 0 12 | # Total Accepted: 58.5K 13 | # Total Submissions: 76.4K 14 | # Testcase Example: '"ababcbacadefegdehijhklij"' 15 | # 16 | # 字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。 17 | # 18 | # 19 | # 20 | # 示例: 21 | # 22 | # 23 | # 输入:S = "ababcbacadefegdehijhklij" 24 | # 输出:[9,7,8] 25 | # 解释: 26 | # 划分结果为 "ababcbaca", "defegde", "hijhklij"。 27 | # 每个字母最多出现在一个片段中。 28 | # 像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。 29 | # 30 | # 31 | # 32 | # 33 | # 提示: 34 | # 35 | # 36 | # S的长度在[1, 500]之间。 37 | # S只包含小写字母 'a' 到 'z' 。 38 | # 39 | # 40 | # 41 | 42 | # @lc code=start 43 | class Solution(object): 44 | def partitionLabels(self, S): 45 | """ 46 | :type S: str 47 | :rtype: List[int] 48 | """ 49 | # @lc code=end 50 | 51 | -------------------------------------------------------------------------------- /11.Greedy/nonOverlap.1.cpp: -------------------------------------------------------------------------------- 1 | int nonOverlapIntervals(vector> &A) { 2 | const int N = A.size(); 3 | 4 | sort(A.begin(), A.end(), [](const vector &a, const vector &b) { 5 | return a[1] != b[1] ? a[1] < b[1] : a[0] < b[0]; 6 | }); 7 | 8 | int preEnd = INT_MIN; 9 | int ans = 0; 10 | for (int i = 0; i < N; i++) { 11 | const int start = A[i][0]; 12 | const int end = A[i][1]; 13 | if (preEnd <= start) { 14 | ans++; 15 | preEnd = end; 16 | } 17 | } 18 | 19 | return ans; 20 | } 21 | -------------------------------------------------------------------------------- /11.Greedy/nonOverlap.1.java: -------------------------------------------------------------------------------- 1 | public int nonOverlapIntervals(int[][] A) { 2 | final int N = A == null ? 0 : A.length; 3 | 4 | Arrays.sort(A, new Comparator() { 5 | public int compare(int[] a, int[] b) { 6 | return a[1] == b[1] ? 0 : (a[1] < b[1] ? -1 : 1); 7 | } 8 | }); 9 | 10 | int preEnd = Integer.MIN_VALUE; 11 | int ans = 0; 12 | 13 | for (int i = 0; i < N; i++) { 14 | final int start = A[i][0]; 15 | if (preEnd <= start) { 16 | preEnd = A[i][1]; 17 | ans++; 18 | } 19 | } 20 | 21 | return ans; 22 | } 23 | -------------------------------------------------------------------------------- /11.Greedy/nonOverlap.1.py: -------------------------------------------------------------------------------- 1 | def nonOverlapIntervals(self, A): 2 | if not A or len(A) == 0: 3 | return 0 4 | 5 | A.sort(key=lambda x: x[1]) 6 | 7 | preEnd = float('-inf') 8 | ans = 0 9 | 10 | for r in A: 11 | start = r[0] 12 | end = r[1] 13 | 14 | if preEnd <= start: 15 | preEnd = end 16 | ans += 1 17 | 18 | return ans 19 | -------------------------------------------------------------------------------- /11.Greedy/nonOverlap.2.cpp: -------------------------------------------------------------------------------- 1 | int nonOverlapIntervals(vector> &A) { 2 | const int N = A.size(); 3 | 4 | sort(A.begin(), A.end()); 5 | 6 | int preStart = INT_MAX; 7 | int ans = 0; 8 | for (int i = N - 1; i >= 0; i--) { 9 | const int end = A[i][1]; 10 | const int start = A[i][0]; 11 | if (end <= preStart) { 12 | ans++; 13 | preStart = A[i][0]; 14 | } 15 | } 16 | 17 | return ans; 18 | } 19 | -------------------------------------------------------------------------------- /11.Greedy/nonOverlap.2.java: -------------------------------------------------------------------------------- 1 | int nonOverlapIntervals(int[][] A) { 2 | final int N = A == null ? 0 : A.length; 3 | 4 | int preStart = Integer.MAX_VALUE; 5 | int ans = 0; 6 | 7 | Arrays.sort(A, new Comparator() { 8 | public int compare(int[] a, int[] b) { 9 | return a[0] == b[0] ? 0 : (a[0] < b[0] ? -1 : 1); 10 | } 11 | }); 12 | 13 | for (int i = N - 1; i >= 0; i--) { 14 | final int start = A[i][0]; 15 | final int end = A[i][1]; 16 | if (end <= preStart) { 17 | preStart = start; 18 | ans++; 19 | } 20 | } 21 | 22 | return ans; 23 | } 24 | -------------------------------------------------------------------------------- /11.Greedy/nonOverlap.2.py: -------------------------------------------------------------------------------- 1 | def nonOverlapIntervals(self, A): 2 | if not A or len(A) == 0: 3 | return 0 4 | 5 | A.sort(key=lambda x: x[0]) 6 | 7 | preStart = float('inf') 8 | ans = 0 9 | 10 | N = len(A) 11 | 12 | for i in range(N-1,-1,-1): 13 | start = A[i][0] 14 | end = A[i][1] 15 | 16 | if end <= preStart: 17 | ans += 1 18 | preStart = start 19 | 20 | return ans 21 | -------------------------------------------------------------------------------- /12.BackTrack/17.电话号码的字母组合.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=17 lang=cpp 3 | * 4 | * [17] 电话号码的字母组合 5 | * 6 | * https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/description/ 7 | * 8 | * algorithms 9 | * Medium (56.04%) 10 | * Likes: 1190 11 | * Dislikes: 0 12 | * Total Accepted: 237K 13 | * Total Submissions: 422K 14 | * Testcase Example: '"23"' 15 | * 16 | * 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 17 | * 任意顺序 返回。 18 | * 19 | * 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 20 | * 21 | * 22 | * 23 | * 24 | * 25 | * 示例 1: 26 | * 27 | * 28 | * 输入:digits = "23" 29 | * 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"] 30 | * 31 | * 32 | * 示例 2: 33 | * 34 | * 35 | * 输入:digits = "" 36 | * 输出:[] 37 | * 38 | * 39 | * 示例 3: 40 | * 41 | * 42 | * 输入:digits = "2" 43 | * 输出:["a","b","c"] 44 | * 45 | * 46 | * 47 | * 48 | * 提示: 49 | * 50 | * 51 | * 0 52 | * digits[i] 是范围 ['2', '9'] 的一个数字。 53 | * 54 | * 55 | */ 56 | 57 | // @lc code=start 58 | class Solution { 59 | public: 60 | vector letterCombinations(string A) {} 61 | }; 62 | // @lc code=end 63 | -------------------------------------------------------------------------------- /12.BackTrack/216.组合总和-iii.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=216 lang=cpp 3 | * 4 | * [216] 组合总和 III 5 | * 6 | * https://leetcode-cn.com/problems/combination-sum-iii/description/ 7 | * 8 | * algorithms 9 | * Medium (73.85%) 10 | * Likes: 281 11 | * Dislikes: 0 12 | * Total Accepted: 69.2K 13 | * Total Submissions: 93.7K 14 | * Testcase Example: '3\n7' 15 | * 16 | * 找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。 17 | * 18 | * 说明: 19 | * 20 | * 21 | * 所有数字都是正整数。 22 | * 解集不能包含重复的组合。  23 | * 24 | * 25 | * 示例 1: 26 | * 27 | * 输入: k = 3, n = 7 28 | * 输出: [[1,2,4]] 29 | * 30 | * 31 | * 示例 2: 32 | * 33 | * 输入: k = 3, n = 9 34 | * 输出: [[1,2,6], [1,3,5], [2,3,4]] 35 | * 36 | * 37 | */ 38 | 39 | // @lc code=start 40 | class Solution { 41 | public: 42 | vector> combinationSum3(int k, int n) { 43 | 44 | } 45 | }; 46 | // @lc code=end 47 | 48 | -------------------------------------------------------------------------------- /12.BackTrack/216.组合总和-iii.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=216 lang=java 3 | * 4 | * [216] 组合总和 III 5 | * 6 | * https://leetcode-cn.com/problems/combination-sum-iii/description/ 7 | * 8 | * algorithms 9 | * Medium (73.85%) 10 | * Likes: 281 11 | * Dislikes: 0 12 | * Total Accepted: 69.2K 13 | * Total Submissions: 93.7K 14 | * Testcase Example: '3\n7' 15 | * 16 | * 找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。 17 | * 18 | * 说明: 19 | * 20 | * 21 | * 所有数字都是正整数。 22 | * 解集不能包含重复的组合。  23 | * 24 | * 25 | * 示例 1: 26 | * 27 | * 输入: k = 3, n = 7 28 | * 输出: [[1,2,4]] 29 | * 30 | * 31 | * 示例 2: 32 | * 33 | * 输入: k = 3, n = 9 34 | * 输出: [[1,2,6], [1,3,5], [2,3,4]] 35 | * 36 | * 37 | */ 38 | 39 | // @lc code=start 40 | class Solution { 41 | public List> combinationSum3(int k, int n) { 42 | 43 | } 44 | } 45 | // @lc code=end 46 | 47 | -------------------------------------------------------------------------------- /12.BackTrack/216.组合总和-iii.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=216 lang=python 3 | # 4 | # [216] 组合总和 III 5 | # 6 | # https://leetcode-cn.com/problems/combination-sum-iii/description/ 7 | # 8 | # algorithms 9 | # Medium (73.85%) 10 | # Likes: 281 11 | # Dislikes: 0 12 | # Total Accepted: 69.2K 13 | # Total Submissions: 93.7K 14 | # Testcase Example: '3\n7' 15 | # 16 | # 找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。 17 | # 18 | # 说明: 19 | # 20 | # 21 | # 所有数字都是正整数。 22 | # 解集不能包含重复的组合。  23 | # 24 | # 25 | # 示例 1: 26 | # 27 | # 输入: k = 3, n = 7 28 | # 输出: [[1,2,4]] 29 | # 30 | # 31 | # 示例 2: 32 | # 33 | # 输入: k = 3, n = 9 34 | # 输出: [[1,2,6], [1,3,5], [2,3,4]] 35 | # 36 | # 37 | # 38 | 39 | # @lc code=start 40 | class Solution(object): 41 | def combinationSum3(self, k, n): 42 | """ 43 | :type k: int 44 | :type n: int 45 | :rtype: List[List[int]] 46 | """ 47 | # @lc code=end 48 | 49 | -------------------------------------------------------------------------------- /12.BackTrack/77.组合.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=77 lang=cpp 3 | * 4 | * [77] 组合 5 | * 6 | * https://leetcode-cn.com/problems/combinations/description/ 7 | * 8 | * algorithms 9 | * Medium (76.55%) 10 | * Likes: 526 11 | * Dislikes: 0 12 | * Total Accepted: 143.1K 13 | * Total Submissions: 186.8K 14 | * Testcase Example: '4\n2' 15 | * 16 | * 给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。 17 | * 18 | * 示例: 19 | * 20 | * 输入: n = 4, k = 2 21 | * 输出: 22 | * [ 23 | * ⁠ [2,4], 24 | * ⁠ [3,4], 25 | * ⁠ [2,3], 26 | * ⁠ [1,2], 27 | * ⁠ [1,3], 28 | * ⁠ [1,4], 29 | * ] 30 | * 31 | */ 32 | 33 | // @lc code=start 34 | class Solution { 35 | void backtrack(int begin, int end, int k, vector &box, 36 | vector> &ans) { 37 | if (box.size() == k) { 38 | ans.push_back(box); 39 | } 40 | 41 | if (box.size() >= k || begin >= end) { 42 | return; 43 | } 44 | 45 | for (int i = begin; i < end; i++) { 46 | box.push_back(i); 47 | backtrack(i + 1, end, k, box, ans); 48 | box.pop_back(); 49 | } 50 | } 51 | 52 | public: 53 | vector> combine(int n, int k) { 54 | vector box; 55 | vector> ans; 56 | backtrack(1, n + 1, k, box, ans); 57 | return ans; 58 | } 59 | }; 60 | // @lc code=end 61 | -------------------------------------------------------------------------------- /12.BackTrack/77.组合.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=77 lang=python 3 | # 4 | # [77] 组合 5 | # 6 | # https://leetcode-cn.com/problems/combinations/description/ 7 | # 8 | # algorithms 9 | # Medium (76.55%) 10 | # Likes: 526 11 | # Dislikes: 0 12 | # Total Accepted: 143.1K 13 | # Total Submissions: 186.8K 14 | # Testcase Example: '4\n2' 15 | # 16 | # 给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。 17 | # 18 | # 示例: 19 | # 20 | # 输入: n = 4, k = 2 21 | # 输出: 22 | # [ 23 | # ⁠ [2,4], 24 | # ⁠ [3,4], 25 | # ⁠ [2,3], 26 | # ⁠ [1,2], 27 | # ⁠ [1,3], 28 | # ⁠ [1,4], 29 | # ] 30 | # 31 | # 32 | 33 | # @lc code=start 34 | class Solution(object): 35 | def append(self, box, ans): 36 | ans.append([]) 37 | for x in box: 38 | ans[-1].append(x) 39 | 40 | def backtrack(self, start, end, k, box, ans): 41 | if len(box) == k: 42 | self.append(box, ans) 43 | 44 | if len(box) >= k or start >= end: 45 | return 46 | 47 | for i in range(start, end): 48 | box.append(i) 49 | self.backtrack(i + 1, end, k, box, ans) 50 | box.pop() 51 | 52 | def combine(self, n, k): 53 | box = [] 54 | ans = [] 55 | self.backtrack(1, n + 1, k, box, ans) 56 | 57 | return ans 58 | # @lc code=end 59 | 60 | -------------------------------------------------------------------------------- /13.DFS.BFS/120.三角形最小路径和.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=120 lang=cpp 3 | * 4 | * [120] 三角形最小路径和 5 | * 6 | * https://leetcode-cn.com/problems/triangle/description/ 7 | * 8 | * algorithms 9 | * Medium (67.24%) 10 | * Likes: 717 11 | * Dislikes: 0 12 | * Total Accepted: 137.1K 13 | * Total Submissions: 203.9K 14 | * Testcase Example: '[[2],[3,4],[6,5,7],[4,1,8,3]]' 15 | * 16 | * 给定一个三角形 triangle ,找出自顶向下的最小路径和。 17 | * 18 | * 每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 19 | * 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。 20 | * 21 | * 22 | * 23 | * 示例 1: 24 | * 25 | * 26 | * 输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]] 27 | * 输出:11 28 | * 解释:如下面简图所示: 29 | * ⁠ 2 30 | * ⁠ 3 4 31 | * ⁠6 5 7 32 | * 4 1 8 3 33 | * 自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。 34 | * 35 | * 36 | * 示例 2: 37 | * 38 | * 39 | * 输入:triangle = [[-10]] 40 | * 输出:-10 41 | * 42 | * 43 | * 44 | * 45 | * 提示: 46 | * 47 | * 48 | * 1 49 | * triangle[0].length == 1 50 | * triangle[i].length == triangle[i - 1].length + 1 51 | * -10^4 52 | * 53 | * 54 | * 55 | * 56 | * 进阶: 57 | * 58 | * 59 | * 你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题吗? 60 | * 61 | * 62 | */ 63 | 64 | // @lc code=start 65 | class Solution { 66 | public: 67 | int minimumTotal(vector>& triangle) { 68 | 69 | } 70 | }; 71 | // @lc code=end 72 | 73 | -------------------------------------------------------------------------------- /13.DFS.BFS/120.三角形最小路径和.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=120 lang=java 3 | * 4 | * [120] 三角形最小路径和 5 | * 6 | * https://leetcode-cn.com/problems/triangle/description/ 7 | * 8 | * algorithms 9 | * Medium (67.24%) 10 | * Likes: 717 11 | * Dislikes: 0 12 | * Total Accepted: 137.1K 13 | * Total Submissions: 203.9K 14 | * Testcase Example: '[[2],[3,4],[6,5,7],[4,1,8,3]]' 15 | * 16 | * 给定一个三角形 triangle ,找出自顶向下的最小路径和。 17 | * 18 | * 每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 19 | * 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。 20 | * 21 | * 22 | * 23 | * 示例 1: 24 | * 25 | * 26 | * 输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]] 27 | * 输出:11 28 | * 解释:如下面简图所示: 29 | * ⁠ 2 30 | * ⁠ 3 4 31 | * ⁠6 5 7 32 | * 4 1 8 3 33 | * 自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。 34 | * 35 | * 36 | * 示例 2: 37 | * 38 | * 39 | * 输入:triangle = [[-10]] 40 | * 输出:-10 41 | * 42 | * 43 | * 44 | * 45 | * 提示: 46 | * 47 | * 48 | * 1 49 | * triangle[0].length == 1 50 | * triangle[i].length == triangle[i - 1].length + 1 51 | * -10^4 52 | * 53 | * 54 | * 55 | * 56 | * 进阶: 57 | * 58 | * 59 | * 你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题吗? 60 | * 61 | * 62 | */ 63 | 64 | // @lc code=start 65 | class Solution { 66 | public int minimumTotal(List> triangle) { 67 | 68 | } 69 | } 70 | // @lc code=end 71 | 72 | -------------------------------------------------------------------------------- /13.DFS.BFS/120.三角形最小路径和.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=120 lang=python 3 | # 4 | # [120] 三角形最小路径和 5 | # 6 | # https://leetcode-cn.com/problems/triangle/description/ 7 | # 8 | # algorithms 9 | # Medium (67.24%) 10 | # Likes: 717 11 | # Dislikes: 0 12 | # Total Accepted: 137.1K 13 | # Total Submissions: 203.9K 14 | # Testcase Example: '[[2],[3,4],[6,5,7],[4,1,8,3]]' 15 | # 16 | # 给定一个三角形 triangle ,找出自顶向下的最小路径和。 17 | # 18 | # 每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 19 | # 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。 20 | # 21 | # 22 | # 23 | # 示例 1: 24 | # 25 | # 26 | # 输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]] 27 | # 输出:11 28 | # 解释:如下面简图所示: 29 | # ⁠ 2 30 | # ⁠ 3 4 31 | # ⁠6 5 7 32 | # 4 1 8 3 33 | # 自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。 34 | # 35 | # 36 | # 示例 2: 37 | # 38 | # 39 | # 输入:triangle = [[-10]] 40 | # 输出:-10 41 | # 42 | # 43 | # 44 | # 45 | # 提示: 46 | # 47 | # 48 | # 1 49 | # triangle[0].length == 1 50 | # triangle[i].length == triangle[i - 1].length + 1 51 | # -10^4 52 | # 53 | # 54 | # 55 | # 56 | # 进阶: 57 | # 58 | # 59 | # 你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题吗? 60 | # 61 | # 62 | # 63 | 64 | # @lc code=start 65 | class Solution(object): 66 | def minimumTotal(self, triangle): 67 | """ 68 | :type triangle: List[List[int]] 69 | :rtype: int 70 | """ 71 | # @lc code=end 72 | 73 | -------------------------------------------------------------------------------- /13.DFS.BFS/22.DP/22.括号生成.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=22 lang=cpp 3 | * 4 | * [22] 括号生成 5 | */ 6 | 7 | // @lc code=start 8 | class Solution { 9 | vector> G{ 10 | {""}, 11 | }; 12 | 13 | public: 14 | vector generateParenthesis(int n) { 15 | if (n <= 0) { 16 | return {}; 17 | } 18 | while (G.size() <= n) { 19 | const int s = G.size(); 20 | G.emplace_back(); 21 | auto &cur = G.back(); 22 | for (int j = 0; j < s; j++) { 23 | auto &l = G[j]; 24 | auto &r = G[s - j - 1]; 25 | for (auto &u : l) { 26 | for (auto &v : r) { 27 | cur.push_back("(" + u + ")" + v); 28 | } 29 | } 30 | } 31 | } 32 | 33 | return G[n]; 34 | } 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /13.DFS.BFS/22.DP/22.括号生成.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=22 lang=java 3 | * 4 | * [22] 括号生成 5 | */ 6 | 7 | // @lc code=start 8 | class Solution { 9 | private List first = new ArrayList<>(); 10 | private List> G = new ArrayList<>(); 11 | public List generateParenthesis(int n) { 12 | List ans = new ArrayList<>(); 13 | if (n <= 0) { 14 | return ans; 15 | } 16 | 17 | if (G.size() == 0) { 18 | first.add(""); 19 | G.add(first); 20 | } 21 | 22 | while (G.size() <= n) { 23 | List cur = new ArrayList<>(); 24 | for (int j = 0; j < G.size(); j++) { 25 | List L = G.get(j); 26 | List R = G.get(G.size() - j - 1); 27 | for (String l: L) { 28 | for (String r: R) { 29 | cur.add("(" + l + ")" + r); 30 | } 31 | } 32 | } 33 | G.add(cur); 34 | } 35 | 36 | return G.get(n); 37 | } 38 | } 39 | // @lc code=end 40 | 41 | -------------------------------------------------------------------------------- /13.DFS.BFS/22.DP/22.括号生成.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=22 lang=python 3 | # 4 | # [22] 括号生成 5 | # 6 | 7 | # @lc code=start 8 | 9 | 10 | class Solution(object): 11 | GG = [[""]] 12 | 13 | def generateParenthesis(self, n): 14 | """ 15 | :type n: int 16 | :rtype: List[str] 17 | """ 18 | 19 | G = self.GG 20 | 21 | if n <= 0: 22 | return [] 23 | 24 | while len(G) <= n: 25 | cur = [] 26 | for j in range(len(G)): 27 | l = G[j] 28 | r = G[len(G)-j-1] 29 | for x in l: 30 | for y in r: 31 | cur.append('(' + x + ')' + y) 32 | G.append(cur) 33 | 34 | return G[n] 35 | 36 | # @lc code=end 37 | -------------------------------------------------------------------------------- /13.DFS.BFS/22.回溯/22.括号生成.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | void backtrace(int n, int idx, int left_cnt, int right_cnt, string &path, 3 | vector &ans) { 4 | if (idx == n + n) { 5 | if (left_cnt == right_cnt) { 6 | ans.push_back(path); 7 | } 8 | } else { 9 | if (left_cnt >= right_cnt && left_cnt < n) { 10 | path.push_back('('); 11 | backtrace(n, idx + 1, left_cnt + 1, right_cnt, path, ans); 12 | path.pop_back(); 13 | } 14 | if (left_cnt > right_cnt) { 15 | path.push_back(')'); 16 | backtrace(n, idx + 1, left_cnt, right_cnt + 1, path, ans); 17 | path.pop_back(); 18 | } 19 | } 20 | } 21 | 22 | public: 23 | vector generateParenthesis(int n) { 24 | if (n <= 0) { 25 | return {}; 26 | } 27 | vector ans; 28 | string path; 29 | backtrace(n, 0, 0, 0, path, ans); 30 | return ans; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /13.DFS.BFS/22.回溯/22.括号生成.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=22 lang=java 3 | * 4 | * [22] 括号生成 5 | */ 6 | 7 | // @lc code=start 8 | class Solution { 9 | private void backTrace(int n, int idx, int lcnt, int rcnt, StringBuilder path, List ans) { 10 | if (idx == (n + n) && lcnt == rcnt) { 11 | ans.add(path.toString()); 12 | } else { 13 | if (lcnt >= rcnt && lcnt < n) { 14 | path.append('('); 15 | backTrace(n, idx + 1, lcnt + 1, rcnt, path, ans); 16 | path.setLength(path.length() - 1); 17 | } 18 | 19 | if (lcnt > rcnt) { 20 | path.append(')'); 21 | backTrace(n, idx + 1, lcnt, rcnt + 1, path, ans); 22 | path.setLength(path.length() - 1); 23 | } 24 | } 25 | } 26 | public List generateParenthesis(int n) { 27 | List ans = new ArrayList<>(); 28 | if (n <= 0) { 29 | return ans; 30 | } 31 | StringBuilder path = new StringBuilder(); 32 | backTrace(n, 0, 0, 0, path, ans); 33 | return ans; 34 | } 35 | } 36 | // @lc code=end 37 | 38 | -------------------------------------------------------------------------------- /13.DFS.BFS/22.回溯/22.括号生成.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=22 lang=python 3 | # 4 | # [22] 括号生成 5 | # 6 | 7 | # @lc code=start 8 | 9 | 10 | class Solution(object): 11 | def backtrace(self, n, idx, lcnt, rcnt, path, ans): 12 | if idx == (n + n): 13 | if lcnt == rcnt: 14 | ans.append(path) 15 | else: 16 | if lcnt >= rcnt and lcnt < n: 17 | path = path + '(' 18 | self.backtrace(n, idx + 1, lcnt + 1, rcnt, path, ans) 19 | path = path[:-1] 20 | 21 | if lcnt > rcnt: 22 | path = path + ')' 23 | self.backtrace(n, idx + 1, lcnt, rcnt + 1, path, ans) 24 | path = path[:-1] 25 | 26 | def generateParenthesis(self, n): 27 | """ 28 | :type n: int 29 | :rtype: List[str] 30 | """ 31 | 32 | if n <= 0: 33 | return [] 34 | 35 | ans = [] 36 | path = "" 37 | 38 | self.backtrace(n, 0, 0, 0, path, ans) 39 | 40 | return ans 41 | # @lc code=end 42 | -------------------------------------------------------------------------------- /13.DFS.BFS/22.队列/22.括号生成.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=22 lang=cpp 3 | * 4 | * [22] 括号生成 5 | */ 6 | 7 | // @lc code=start 8 | class Solution { 9 | public: 10 | vector generateParenthesis(int n) { 11 | 12 | } 13 | }; 14 | // @lc code=end 15 | 16 | -------------------------------------------------------------------------------- /13.DFS.BFS/279.完全平方数.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=279 lang=java 3 | * 4 | * [279] 完全平方数 5 | * 6 | * https://leetcode-cn.com/problems/perfect-squares/description/ 7 | * 8 | * algorithms 9 | * Medium (59.76%) 10 | * Likes: 808 11 | * Dislikes: 0 12 | * Total Accepted: 121.7K 13 | * Total Submissions: 203.6K 14 | * Testcase Example: '12' 15 | * 16 | * 给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。 17 | * 18 | * 给你一个整数 n ,返回和为 n 的完全平方数的 最少数量 。 19 | * 20 | * 完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 21 | * 不是。 22 | * 23 | * 24 | * 25 | * 示例 1: 26 | * 27 | * 28 | * 输入:n = 12 29 | * 输出:3 30 | * 解释:12 = 4 + 4 + 4 31 | * 32 | * 示例 2: 33 | * 34 | * 35 | * 输入:n = 13 36 | * 输出:2 37 | * 解释:13 = 4 + 9 38 | * 39 | * 40 | * 提示: 41 | * 42 | * 43 | * 1 44 | * 45 | * 46 | */ 47 | 48 | // @lc code=start 49 | class Solution { 50 | public int numSquares(int n) { 51 | 52 | } 53 | } 54 | // @lc code=end 55 | 56 | -------------------------------------------------------------------------------- /13.DFS.BFS/713.乘积小于k的子数组.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=713 lang=cpp 3 | * 4 | * [713] 乘积小于K的子数组 5 | * 6 | * https://leetcode-cn.com/problems/subarray-product-less-than-k/description/ 7 | * 8 | * algorithms 9 | * Medium (37.56%) 10 | * Likes: 224 11 | * Dislikes: 0 12 | * Total Accepted: 12.1K 13 | * Total Submissions: 32.2K 14 | * Testcase Example: '[10,5,2,6]\n100' 15 | * 16 | * 给定一个正整数数组 nums。 17 | * 18 | * 找出该数组内乘积小于 k 的连续的子数组的个数。 19 | * 20 | * 示例 1: 21 | * 22 | * 23 | * 输入: nums = [10,5,2,6], k = 100 24 | * 输出: 8 25 | * 解释: 8个乘积小于100的子数组分别为: [10], [5], [2], [6], [10,5], [5,2], 26 | * [2,6], [5,2,6]。 需要注意的是 [10,5,2] 并不是乘积小于100的子数组。 27 | * 28 | * 29 | * 说明: 30 | * 31 | * 32 | * 0 < nums.length <= 50000 33 | * 0 < nums[i] < 1000 34 | * 0 <= k < 10^6 35 | * 36 | * 37 | */ 38 | 39 | // @lc code=start 40 | class Solution { 41 | public: 42 | int numSubarrayProductLessThanK(vector& A, int k) { 43 | const int N = A.size(); 44 | int64_t s = 1; 45 | int left = -1; 46 | int ans = 0; 47 | 48 | for (int i = 0; i < N; i++) { 49 | s *= A[i]; 50 | 51 | while (left < i && s >= k) { 52 | s /= A[++left]; 53 | } 54 | 55 | ans += i - left; 56 | } 57 | return ans; 58 | } 59 | }; 60 | // @lc code=end 61 | -------------------------------------------------------------------------------- /13.DFS.BFS/713.乘积小于k的子数组.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=713 lang=python 3 | # 4 | # [713] 乘积小于K的子数组 5 | # 6 | # https://leetcode-cn.com/problems/subarray-product-less-than-k/description/ 7 | # 8 | # algorithms 9 | # Medium (37.56%) 10 | # Likes: 224 11 | # Dislikes: 0 12 | # Total Accepted: 12.1K 13 | # Total Submissions: 32.2K 14 | # Testcase Example: '[10,5,2,6]\n100' 15 | # 16 | # 给定一个正整数数组 nums。 17 | # 18 | # 找出该数组内乘积小于 k 的连续的子数组的个数。 19 | # 20 | # 示例 1: 21 | # 22 | # 23 | # 输入: nums = [10,5,2,6], k = 100 24 | # 输出: 8 25 | # 解释: 8个乘积小于100的子数组分别为: [10], [5], [2], [6], [10,5], [5,2], [2,6], [5,2,6]。 26 | # 需要注意的是 [10,5,2] 并不是乘积小于100的子数组。 27 | # 28 | # 29 | # 说明: 30 | # 31 | # 32 | # 0 < nums.length <= 50000 33 | # 0 < nums[i] < 1000 34 | # 0 <= k < 10^6 35 | # 36 | # 37 | # 38 | 39 | # @lc code=start 40 | class Solution(object): 41 | def numSubarrayProductLessThanK(self, A, k): 42 | N = 0 if not A else len(A) 43 | s = 1 44 | left = -1 45 | ans = 0 46 | 47 | for i in range(N): 48 | s *= A[i] 49 | while s >= k and left < i: 50 | left += 1 51 | s /= A[left] 52 | 53 | ans += i - left 54 | 55 | return ans 56 | 57 | # @lc code=end 58 | 59 | -------------------------------------------------------------------------------- /13.DFS.BFS/783._Minimum_Risk_Path.py: -------------------------------------------------------------------------------- 1 | # https://www.lintcode.com/problem/minimum-risk-path/ 2 | 3 | import heapq 4 | # 构建 5 | # heapq.heapify(heap) 6 | # pop 7 | # cur = heapq.heappop(heap) 8 | # push 9 | # heapq.heappush(heap, cur.next) 10 | 11 | class Solution: 12 | """ 13 | @param n: maximum index of position. 14 | @param m: the number of undirected edges. 15 | @param x: 16 | @param y: 17 | @param w: 18 | @return: return the minimum risk value. 19 | """ 20 | def getMinRiskValue(self, n, m, x, y, w): 21 | G = [] 22 | for i in range(n+1): 23 | G.append([]) 24 | 25 | # 构建图 26 | for i in range(m): 27 | a = x[i] 28 | b = y[i] 29 | c = w[i] 30 | G[a].append([b,c]) 31 | G[b].append([a,c]) 32 | 33 | Q = [] 34 | 35 | INF = 2147483647 36 | risk = [INF] * (n+1) 37 | risk[0] = 0 38 | 39 | # push 40 | heapq.heappush(Q, [0, 0]) 41 | 42 | while len(Q) > 0: 43 | cRisk, cNode = heapq.heappop(Q) 44 | # 拿当前结点的后续 45 | for nextInfo in G[cNode]: 46 | next = nextInfo[0] 47 | nextRisk = max(cRisk, nextInfo[1]) 48 | if nextRisk < risk[next]: 49 | risk[next] = nextRisk 50 | heapq.heappush(Q, [nextRisk, next]) 51 | 52 | return risk[n] 53 | 54 | -------------------------------------------------------------------------------- /13.DFS.BFS/Solution.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lagoueduCol/Algorithm-Dryad/c11331df1eadb8fbcdf3ae5615eb5ddc9b4c414c/13.DFS.BFS/Solution.class -------------------------------------------------------------------------------- /13.DFS.BFS/八皇后.cpp: -------------------------------------------------------------------------------- 1 | // 八皇后 https://leetcode-cn.com/problems/eight-queens-lcci/ 2 | class Solution { 3 | int N = 0; 4 | vector row; 5 | vector left; 6 | vector right; 7 | vector A; 8 | vector> ans; 9 | void dfs(int c) { 10 | // 如果每一列都填满了 11 | if (c == N) { 12 | ans.push_back(A); 13 | return; 14 | } 15 | 16 | // 每一列有N行的选择 17 | for (int r = 0; r < N; r++) { 18 | // 如果会被攻击 19 | if (row[r] || left[r+c] || right[r+N-c]) { 20 | continue; 21 | } 22 | 23 | A[r][c] = 'Q'; 24 | row[r] = true; 25 | left[r+c] = true; 26 | right[r+N-c] = true; 27 | dfs(c + 1); 28 | A[r][c] = '.'; 29 | row[r] = false; 30 | left[r+c] = false; 31 | right[r+N-c] = false; 32 | } 33 | } 34 | public: 35 | vector> &solveNQueens(int n) { 36 | // 将结果矩阵清空 37 | ans.clear(); 38 | // 记住正方形 39 | N = n; 40 | A.clear(); 41 | A.resize(N, string(N, '.')); 42 | 43 | // 对角线的计算方式 44 | // A: i + j 45 | // 如果是 \ 方向上的对角线 46 | // B: i + C - j 47 | row.resize(N, false); 48 | left.resize(N + N, false); 49 | right.resize(N + N, false); 50 | 51 | // 求解 52 | dfs(0); 53 | 54 | return ans; 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /14.DP/416.分割等和子集.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=416 lang=python 3 | # 4 | # [416] 分割等和子集 5 | # 6 | # https://leetcode-cn.com/problems/partition-equal-subset-sum/description/ 7 | # 8 | # algorithms 9 | # Medium (49.67%) 10 | # Likes: 739 11 | # Dislikes: 0 12 | # Total Accepted: 115.5K 13 | # Total Submissions: 232.4K 14 | # Testcase Example: '[1,5,11,5]' 15 | # 16 | # 给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 17 | # 18 | # 注意: 19 | # 20 | # 21 | # 每个数组中的元素不会超过 100 22 | # 数组的大小不会超过 200 23 | # 24 | # 25 | # 示例 1: 26 | # 27 | # 输入: [1, 5, 11, 5] 28 | # 29 | # 输出: true 30 | # 31 | # 解释: 数组可以分割成 [1, 5, 5] 和 [11]. 32 | # 33 | # 34 | # 35 | # 36 | # 示例 2: 37 | # 38 | # 输入: [1, 2, 3, 5] 39 | # 40 | # 输出: false 41 | # 42 | # 解释: 数组不能分割成两个元素和相等的子集. 43 | # 44 | # 45 | # 46 | # 47 | # 48 | 49 | # @lc code=start 50 | class Solution(object): 51 | def canPartition(self, A): 52 | N = 0 if not A else len(A) 53 | s = sum(A) 54 | 55 | if (s % 2) == 1: 56 | return False 57 | 58 | # V表示0/1背包中我们需要填充的容量 59 | V = s // 2 60 | dp = [False]*(V+1) 61 | dp[0] = True 62 | 63 | for x in A: 64 | for node in range(V,x-1,-1): 65 | oldNode = node - x 66 | newNode = node 67 | if dp[oldNode]: 68 | dp[newNode] = True 69 | 70 | return dp[V] 71 | # @lc code=end 72 | 73 | -------------------------------------------------------------------------------- /14.DP/837.新-21-点.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=837 lang=cpp 3 | * 4 | * [837] 新21点 5 | * 6 | * https://leetcode-cn.com/problems/new-21-game/description/ 7 | * 8 | * algorithms 9 | * Medium (39.73%) 10 | * Likes: 283 11 | * Dislikes: 0 12 | * Total Accepted: 18.6K 13 | * Total Submissions: 46.9K 14 | * Testcase Example: '10\n1\n10' 15 | * 16 | * 爱丽丝参与一个大致基于纸牌游戏 “21点” 规则的游戏,描述如下: 17 | * 18 | * 爱丽丝以 0 分开始,并在她的得分少于 K 分时抽取数字。 抽取时,她从 [1, W] 的范围中随机获得一个整数作为分数进行累计,其中 W 是整数。 19 | * 每次抽取都是独立的,其结果具有相同的概率。 20 | * 21 | * 当爱丽丝获得不少于 K 分时,她就停止抽取数字。 爱丽丝的分数不超过 N 的概率是多少? 22 | * 23 | * 24 | * 25 | * 示例 1: 26 | * 27 | * 输入:N = 10, K = 1, W = 10 28 | * 输出:1.00000 29 | * 说明:爱丽丝得到一张卡,然后停止。 30 | * 31 | * 示例 2: 32 | * 33 | * 输入:N = 6, K = 1, W = 10 34 | * 输出:0.60000 35 | * 说明:爱丽丝得到一张卡,然后停止。 36 | * 在 W = 10 的 6 种可能下,她的得分不超过 N = 6 分。 37 | * 38 | * 示例 3: 39 | * 40 | * 输入:N = 21, K = 17, W = 10 41 | * 输出:0.73278 42 | * 43 | * 44 | * 45 | * 提示: 46 | * 47 | * 48 | * 0 <= K <= N <= 10000 49 | * 1 <= W <= 10000 50 | * 如果答案与正确答案的误差不超过 10^-5,则该答案将被视为正确答案通过。 51 | * 此问题的判断限制时间已经减少。 52 | * 53 | * 54 | */ 55 | 56 | // @lc code=start 57 | class Solution { 58 | public: 59 | double new21Game(int N, int K, int W) { 60 | 61 | } 62 | }; 63 | // @lc code=end 64 | 65 | -------------------------------------------------------------------------------- /14.DP/837.新-21-点.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=837 lang=java 3 | * 4 | * [837] 新21点 5 | * 6 | * https://leetcode-cn.com/problems/new-21-game/description/ 7 | * 8 | * algorithms 9 | * Medium (39.73%) 10 | * Likes: 283 11 | * Dislikes: 0 12 | * Total Accepted: 18.6K 13 | * Total Submissions: 46.9K 14 | * Testcase Example: '10\n1\n10' 15 | * 16 | * 爱丽丝参与一个大致基于纸牌游戏 “21点” 规则的游戏,描述如下: 17 | * 18 | * 爱丽丝以 0 分开始,并在她的得分少于 K 分时抽取数字。 抽取时,她从 [1, W] 的范围中随机获得一个整数作为分数进行累计,其中 W 是整数。 19 | * 每次抽取都是独立的,其结果具有相同的概率。 20 | * 21 | * 当爱丽丝获得不少于 K 分时,她就停止抽取数字。 爱丽丝的分数不超过 N 的概率是多少? 22 | * 23 | * 24 | * 25 | * 示例 1: 26 | * 27 | * 输入:N = 10, K = 1, W = 10 28 | * 输出:1.00000 29 | * 说明:爱丽丝得到一张卡,然后停止。 30 | * 31 | * 示例 2: 32 | * 33 | * 输入:N = 6, K = 1, W = 10 34 | * 输出:0.60000 35 | * 说明:爱丽丝得到一张卡,然后停止。 36 | * 在 W = 10 的 6 种可能下,她的得分不超过 N = 6 分。 37 | * 38 | * 示例 3: 39 | * 40 | * 输入:N = 21, K = 17, W = 10 41 | * 输出:0.73278 42 | * 43 | * 44 | * 45 | * 提示: 46 | * 47 | * 48 | * 0 <= K <= N <= 10000 49 | * 1 <= W <= 10000 50 | * 如果答案与正确答案的误差不超过 10^-5,则该答案将被视为正确答案通过。 51 | * 此问题的判断限制时间已经减少。 52 | * 53 | * 54 | */ 55 | 56 | // @lc code=start 57 | class Solution { 58 | public double new21Game(int N, int K, int W) { 59 | 60 | } 61 | } 62 | // @lc code=end 63 | 64 | -------------------------------------------------------------------------------- /14.DP/837.新-21-点.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=837 lang=python 3 | # 4 | # [837] 新21点 5 | # 6 | # https://leetcode-cn.com/problems/new-21-game/description/ 7 | # 8 | # algorithms 9 | # Medium (39.73%) 10 | # Likes: 283 11 | # Dislikes: 0 12 | # Total Accepted: 18.6K 13 | # Total Submissions: 46.9K 14 | # Testcase Example: '10\n1\n10' 15 | # 16 | # 爱丽丝参与一个大致基于纸牌游戏 “21点” 规则的游戏,描述如下: 17 | # 18 | # 爱丽丝以 0 分开始,并在她的得分少于 K 分时抽取数字。 抽取时,她从 [1, W] 的范围中随机获得一个整数作为分数进行累计,其中 W 是整数。 19 | # 每次抽取都是独立的,其结果具有相同的概率。 20 | # 21 | # 当爱丽丝获得不少于 K 分时,她就停止抽取数字。 爱丽丝的分数不超过 N 的概率是多少? 22 | # 23 | # 24 | # 25 | # 示例 1: 26 | # 27 | # 输入:N = 10, K = 1, W = 10 28 | # 输出:1.00000 29 | # 说明:爱丽丝得到一张卡,然后停止。 30 | # 31 | # 示例 2: 32 | # 33 | # 输入:N = 6, K = 1, W = 10 34 | # 输出:0.60000 35 | # 说明:爱丽丝得到一张卡,然后停止。 36 | # 在 W = 10 的 6 种可能下,她的得分不超过 N = 6 分。 37 | # 38 | # 示例 3: 39 | # 40 | # 输入:N = 21, K = 17, W = 10 41 | # 输出:0.73278 42 | # 43 | # 44 | # 45 | # 提示: 46 | # 47 | # 48 | # 0 <= K <= N <= 10000 49 | # 1 <= W <= 10000 50 | # 如果答案与正确答案的误差不超过 10^-5,则该答案将被视为正确答案通过。 51 | # 此问题的判断限制时间已经减少。 52 | # 53 | # 54 | # 55 | 56 | # @lc code=start 57 | class Solution(object): 58 | def new21Game(self, N, K, W): 59 | """ 60 | :type N: int 61 | :type K: int 62 | :type W: int 63 | :rtype: float 64 | """ 65 | 66 | # @lc code=end 67 | 68 | -------------------------------------------------------------------------------- /14.DP/acwing.01.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 测试平台 : https://www.acwing.com/problem/content/2/ 3 | 4 | # your code here 5 | class Solution: 6 | def Solve(self, N, V, v, w): 7 | # dp[x]表示当占用掉x空间的容量时 8 | # 能够得到的最大的收益 9 | dp = [0] * (V + 1) 10 | 11 | # 可以认为一开始的点集为S0 = {0/*占用的空间*/, 0/*收益*/} 12 | # 也就是dp[0] = 0 13 | # 但是这里不需要去设置,省略! 14 | ans = 0 15 | 16 | for i in range(N): 17 | # 我们遍历旧有的点集 18 | # 注意遍历的方向 19 | for space in range(V, v[i]-1, -1): 20 | oldSpace = space - v[i] 21 | newSpace = space 22 | 23 | # 当我们选择累加到 24 | # 的时候 25 | # 我们可以得到 26 | # 27 | # 当然,这里我们dp[newSpace] 28 | # 可能原来就有值 29 | # 我们需要取个更大一点的值 30 | dp[newSpace] = max(dp[newSpace], dp[oldSpace] + w[i]) 31 | 32 | ans = max(ans, dp[newSpace]) 33 | 34 | # 最后返回整个数组中的最大值 35 | return ans 36 | 37 | while True: 38 | try: 39 | line = raw_input() 40 | except: 41 | break 42 | ws = line.split() 43 | 44 | N = int(ws[0]) 45 | V = int(ws[1]) 46 | 47 | v = [] 48 | w = [] 49 | for i in range(N): 50 | line = raw_input() 51 | ws = line.split() 52 | vi, wi = ws 53 | v.append(int(vi)) 54 | w.append(int(wi)) 55 | 56 | s = Solution() 57 | print s.Solve(N, V, v, w) -------------------------------------------------------------------------------- /14.DP/acwing.full.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 测试平台 : https://www.acwing.com/problem/content/3/ 3 | 4 | # your code here 5 | class Solution: 6 | def Solve(self, N, V, v, w): 7 | # dp[x]表示当占用掉x空间的容量时 8 | # 能够得到的最大的收益 9 | dp = [0] * (V + 1) 10 | 11 | # 可以认为一开始的点集为S0 = {0/*占用的空间*/, 0/*收益*/} 12 | # 也就是dp[0] = 0 13 | # 但是这里不需要去设置,省略! 14 | 15 | ans = 0 16 | for i in range(N): 17 | # 我们遍历旧有的点集 18 | # 注意遍历的方向 19 | for space in range(v[i], V + 1): 20 | oldSpace = space - v[i] 21 | newSpace = space 22 | 23 | # 当我们选择累加到 24 | # 的时候 25 | # 我们可以得到 26 | # 27 | # 当然,这里我们dp[newSpace] 28 | # 可能原来就有值 29 | # 我们需要取个更大一点的值 30 | dp[newSpace] = max(dp[newSpace], dp[oldSpace] + w[i]) 31 | 32 | ans = max(ans, dp[newSpace]) 33 | 34 | # 最后返回整个数组中的最大值 35 | return ans 36 | 37 | while True: 38 | try: 39 | line = raw_input() 40 | except: 41 | break 42 | ws = line.split() 43 | 44 | N = int(ws[0]) 45 | V = int(ws[1]) 46 | 47 | v = [] 48 | w = [] 49 | for i in range(N): 50 | line = raw_input() 51 | ws = line.split() 52 | vi, wi = ws 53 | v.append(int(vi)) 54 | w.append(int(wi)) 55 | 56 | s = Solution() 57 | print s.Solve(N, V, v, w) 58 | -------------------------------------------------------------------------------- /15.StrStr/214.最短回文串.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=214 lang=cpp 3 | * 4 | * [214] 最短回文串 5 | * 6 | * https://leetcode-cn.com/problems/shortest-palindrome/description/ 7 | * 8 | * algorithms 9 | * Hard (36.75%) 10 | * Likes: 336 11 | * Dislikes: 0 12 | * Total Accepted: 27.3K 13 | * Total Submissions: 74.4K 14 | * Testcase Example: '"aacecaaa"' 15 | * 16 | * 给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。 17 | * 18 | * 19 | * 20 | * 示例 1: 21 | * 22 | * 23 | * 输入:s = "aacecaaa" 24 | * 输出:"aaacecaaa" 25 | * 26 | * 27 | * 示例 2: 28 | * 29 | * 30 | * 输入:s = "abcd" 31 | * 输出:"dcbabcd" 32 | * 33 | * 34 | * 35 | * 36 | * 提示: 37 | * 38 | * 39 | * 0 40 | * s 仅由小写英文字母组成 41 | * 42 | * 43 | */ 44 | 45 | // @lc code=start 46 | class Solution { 47 | public: 48 | string shortestPalindrome(string s) { 49 | 50 | } 51 | }; 52 | // @lc code=end 53 | 54 | -------------------------------------------------------------------------------- /15.StrStr/214.最短回文串.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=214 lang=java 3 | * 4 | * [214] 最短回文串 5 | * 6 | * https://leetcode-cn.com/problems/shortest-palindrome/description/ 7 | * 8 | * algorithms 9 | * Hard (36.75%) 10 | * Likes: 336 11 | * Dislikes: 0 12 | * Total Accepted: 27.3K 13 | * Total Submissions: 74.4K 14 | * Testcase Example: '"aacecaaa"' 15 | * 16 | * 给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。 17 | * 18 | * 19 | * 20 | * 示例 1: 21 | * 22 | * 23 | * 输入:s = "aacecaaa" 24 | * 输出:"aaacecaaa" 25 | * 26 | * 27 | * 示例 2: 28 | * 29 | * 30 | * 输入:s = "abcd" 31 | * 输出:"dcbabcd" 32 | * 33 | * 34 | * 35 | * 36 | * 提示: 37 | * 38 | * 39 | * 0 40 | * s 仅由小写英文字母组成 41 | * 42 | * 43 | */ 44 | 45 | // @lc code=start 46 | class Solution { 47 | public String shortestPalindrome(String s) { 48 | 49 | } 50 | } 51 | // @lc code=end 52 | 53 | -------------------------------------------------------------------------------- /15.StrStr/214.最短回文串.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=214 lang=python 3 | # 4 | # [214] 最短回文串 5 | # 6 | # https://leetcode-cn.com/problems/shortest-palindrome/description/ 7 | # 8 | # algorithms 9 | # Hard (36.75%) 10 | # Likes: 336 11 | # Dislikes: 0 12 | # Total Accepted: 27.3K 13 | # Total Submissions: 74.4K 14 | # Testcase Example: '"aacecaaa"' 15 | # 16 | # 给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。 17 | # 18 | # 19 | # 20 | # 示例 1: 21 | # 22 | # 23 | # 输入:s = "aacecaaa" 24 | # 输出:"aaacecaaa" 25 | # 26 | # 27 | # 示例 2: 28 | # 29 | # 30 | # 输入:s = "abcd" 31 | # 输出:"dcbabcd" 32 | # 33 | # 34 | # 35 | # 36 | # 提示: 37 | # 38 | # 39 | # 0 40 | # s 仅由小写英文字母组成 41 | # 42 | # 43 | # 44 | 45 | # @lc code=start 46 | class Solution(object): 47 | def shortestPalindrome(self, s): 48 | """ 49 | :type s: str 50 | :rtype: str 51 | """ 52 | # @lc code=end 53 | 54 | -------------------------------------------------------------------------------- /15.StrStr/28.实现-str-str.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=28 lang=python 3 | # 4 | # [28] 实现 strStr() 5 | # 6 | # https://leetcode-cn.com/problems/implement-strstr/description/ 7 | # 8 | # algorithms 9 | # Easy (39.71%) 10 | # Likes: 773 11 | # Dislikes: 0 12 | # Total Accepted: 326.5K 13 | # Total Submissions: 822.2K 14 | # Testcase Example: '"hello"\n"ll"' 15 | # 16 | # 实现 strStr() 函数。 17 | # 18 | # 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 19 | # (从0开始)。如果不存在,则返回  -1。 20 | # 21 | # 示例 1: 22 | # 23 | # 输入: haystack = "hello", needle = "ll" 24 | # 输出: 2 25 | # 26 | # 27 | # 示例 2: 28 | # 29 | # 输入: haystack = "aaaaa", needle = "bba" 30 | # 输出: -1 31 | # 32 | # 33 | # 说明: 34 | # 35 | # 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 36 | # 37 | # 对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。 38 | # 39 | # 40 | 41 | # @lc code=start 42 | class Solution(object): 43 | def strStr(self, main, sub): 44 | if not sub or len(sub) == 0: 45 | return 0 46 | 47 | for start in range(0, len(main)): 48 | hasFind = True 49 | 50 | for j in range(0, len(sub)): 51 | if start + j >= len(main) or main[start+j] != sub[j]: 52 | hasFind = False 53 | break 54 | 55 | if hasFind: 56 | return start 57 | 58 | return -1 59 | 60 | # @lc code=end 61 | 62 | -------------------------------------------------------------------------------- /15.StrStr/459.重复的子字符串.mod.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=459 lang=cpp 3 | * 4 | * [459] 重复的子字符串 5 | * 6 | * https://leetcode-cn.com/problems/repeated-substring-pattern/description/ 7 | * 8 | * algorithms 9 | * Easy (51.07%) 10 | * Likes: 482 11 | * Dislikes: 0 12 | * Total Accepted: 66.8K 13 | * Total Submissions: 130.8K 14 | * Testcase Example: '"abab"' 15 | * 16 | * 给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。 17 | * 18 | * 示例 1: 19 | * 20 | * 21 | * 输入: "abab" 22 | * 23 | * 输出: True 24 | * 25 | * 解释: 可由子字符串 "ab" 重复两次构成。 26 | * 27 | * 28 | * 示例 2: 29 | * 30 | * 31 | * 输入: "aba" 32 | * 33 | * 输出: False 34 | * 35 | * 36 | * 示例 3: 37 | * 38 | * 39 | * 输入: "abcabcabcabc" 40 | * 41 | * 输出: True 42 | * 43 | * 解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。) 44 | * 45 | * 46 | */ 47 | 48 | // @lc code=start 49 | class Solution { 50 | public: 51 | bool repeatedSubstringPattern(string s) { 52 | return (s + s).find(s, 1) != s.size(); 53 | } 54 | }; 55 | // @lc code=end 56 | 57 | -------------------------------------------------------------------------------- /15.StrStr/459.重复的子字符串.mod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=459 lang=java 3 | * 4 | * [459] 重复的子字符串 5 | * 6 | * https://leetcode-cn.com/problems/repeated-substring-pattern/description/ 7 | * 8 | * algorithms 9 | * Easy (51.07%) 10 | * Likes: 482 11 | * Dislikes: 0 12 | * Total Accepted: 66.8K 13 | * Total Submissions: 130.8K 14 | * Testcase Example: '"abab"' 15 | * 16 | * 给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。 17 | * 18 | * 示例 1: 19 | * 20 | * 21 | * 输入: "abab" 22 | * 23 | * 输出: True 24 | * 25 | * 解释: 可由子字符串 "ab" 重复两次构成。 26 | * 27 | * 28 | * 示例 2: 29 | * 30 | * 31 | * 输入: "aba" 32 | * 33 | * 输出: False 34 | * 35 | * 36 | * 示例 3: 37 | * 38 | * 39 | * 输入: "abcabcabcabc" 40 | * 41 | * 输出: True 42 | * 43 | * 解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。) 44 | * 45 | * 46 | */ 47 | 48 | // @lc code=start 49 | class Solution { 50 | 51 | public boolean repeatedSubstringPattern(String s) { 52 | return (s + s).indexOf(s, 1) != s.length(); 53 | } 54 | } 55 | // @lc code=end -------------------------------------------------------------------------------- /15.StrStr/459.重复的子字符串.mod.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=459 lang=python 3 | # 4 | # [459] 重复的子字符串 5 | # 6 | # https://leetcode-cn.com/problems/repeated-substring-pattern/description/ 7 | # 8 | # algorithms 9 | # Easy (51.07%) 10 | # Likes: 482 11 | # Dislikes: 0 12 | # Total Accepted: 66.8K 13 | # Total Submissions: 130.8K 14 | # Testcase Example: '"abab"' 15 | # 16 | # 给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。 17 | # 18 | # 示例 1: 19 | # 20 | # 21 | # 输入: "abab" 22 | # 23 | # 输出: True 24 | # 25 | # 解释: 可由子字符串 "ab" 重复两次构成。 26 | # 27 | # 28 | # 示例 2: 29 | # 30 | # 31 | # 输入: "aba" 32 | # 33 | # 输出: False 34 | # 35 | # 36 | # 示例 3: 37 | # 38 | # 39 | # 输入: "abcabcabcabc" 40 | # 41 | # 输出: True 42 | # 43 | # 解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。) 44 | # 45 | # 46 | # 47 | 48 | # @lc code=start 49 | class Solution(object): 50 | def repeatedSubstringPattern(self, s): 51 | return (s + s).find(s, 1) != len(s) 52 | # @lc code=end 53 | 54 | -------------------------------------------------------------------------------- /15.StrStr/BF.C: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lagoueduCol/Algorithm-Dryad/c11331df1eadb8fbcdf3ae5615eb5ddc9b4c414c/15.StrStr/BF.C -------------------------------------------------------------------------------- /15.StrStr/KMP.C: -------------------------------------------------------------------------------- 1 | 2 | void make_next(char *t, int *next) { 3 | int i = 0; 4 | int j = -1; 5 | next[0] = -1; 6 | 7 | while (t[i]) { 8 | if (-1 == j || t[i] == t[j]) { 9 | ++i; 10 | ++j; 11 | // 注意这优化,在往后退的时候,如果发现和下一个退回 12 | // 去的地方的字符是相等的,那么再往后退一下。 13 | // 否则就退到下一个要比较的地方 14 | next[i] = t[i] == t[j] ? next[j] : j; 15 | } else { 16 | j = next[j]; 17 | } 18 | } 19 | } 20 | 21 | int strStr(char * s, char * t){ 22 | if (!t || !*t) { 23 | return 0; 24 | } 25 | 26 | if (!s) { 27 | return -1; 28 | } 29 | 30 | const int tlen = strlen(t); 31 | 32 | int next[tlen + 1]; 33 | make_next(t, next); 34 | 35 | int i = 0, j = 0; 36 | while (s[i] && j < tlen) { 37 | if (-1 == j || s[i] == t[j]) { 38 | i++; 39 | j++; 40 | } else { 41 | j = next[j]; 42 | } 43 | } 44 | 45 | return j == tlen ? i - j : -1; 46 | } 47 | -------------------------------------------------------------------------------- /15.StrStr/Sunday.C: -------------------------------------------------------------------------------- 1 | int strStr(char * s, char * t){ 2 | if (!t || !*t) { 3 | return 0; 4 | } 5 | 6 | if (!s || !*s) { 7 | return -1; 8 | } 9 | 10 | const int slen = strlen(s); 11 | const int tlen = strlen(t); 12 | 13 | if (slen < tlen) { 14 | return -1; 15 | } 16 | 17 | int pos[256]; 18 | memset(pos, -1, sizeof(pos)); 19 | 20 | for (int i = 0; i < tlen; i++) { 21 | pos[t[i]] = i; 22 | } 23 | 24 | for (int i = 0; i <= slen - tlen; i++) { 25 | int j = 0; 26 | while (t[j]) { 27 | if (s[i + j] != t[j]) { 28 | break; 29 | } 30 | j++; 31 | } 32 | 33 | if (j == tlen) { 34 | return i; 35 | } 36 | 37 | const int lastChar = s[i+tlen-1]; 38 | if (lastChar != t[tlen-1]) { 39 | if (pos[lastChar] != -1) { 40 | i += tlen - 1 - pos[lastChar] - 1; 41 | } else { 42 | i = i + tlen - 1; 43 | } 44 | } 45 | } 46 | 47 | return -1; 48 | } 49 | -------------------------------------------------------------------------------- /15.StrStr/next.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector buildNext(string &s) { 4 | const int N = s.length(); 5 | vector next(N+1); 6 | 7 | int i = 0; 8 | int j = -1; 9 | next[0] = -1; 10 | 11 | while (i < N) { 12 | if (-1 == j || s[i] == s[j]) { 13 | i++; 14 | j++; 15 | next[i] = j; 16 | } else { 17 | j = next[j]; 18 | } 19 | } 20 | 21 | // 最后一项就是整个字符串的前后缀的最长匹配 22 | return next; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /15.StrStr/next.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | // 如果一个字符串可以由一个子串重复构成,比如 3 | // AAAA 4 | // 那么前后缀的最长匹配为"AAA" 5 | // 那么s.length() - 这个最长匹配 6 | // 就是得到重复部分的长度 7 | public int[] buildNext(String sub) { 8 | final int N = sub == null ? 0 : sub.length(); 9 | int[] next = new int[N+1]; 10 | 11 | int i = 0; 12 | int j = -1; 13 | 14 | next[0] = -1; 15 | 16 | while (i < N) { 17 | if (-1 == j || sub.charAt(i) == sub.charAt(j)) { 18 | i++; 19 | j++; 20 | next[i] = j; 21 | } else { 22 | j = next[j]; 23 | } 24 | } 25 | 26 | return next; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /15.StrStr/next.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def buildNext(self, s): 3 | N = 0 if not s else len(s) 4 | 5 | next = [0] * (N + 1) 6 | 7 | i = 0 8 | j = -1 9 | 10 | next[0] = -1 11 | 12 | while i < N: 13 | if -1 == j or s[i] == s[j]: 14 | i += 1 15 | j += 1 16 | next[i] = j 17 | else: 18 | j = next[j] 19 | return next 20 | -------------------------------------------------------------------------------- /15.StrStr/pmt.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector buildPMT(string &s) { 4 | const int N = s.length(); 5 | vector pmt(N); 6 | 7 | int i = 1; 8 | int j = 0; 9 | 10 | pmt[0] = 0; 11 | 12 | while (i < N) { 13 | if (s[i] == s[j]) { 14 | i++; 15 | j++; 16 | pmt[i-1] = j; 17 | } else { 18 | if (0 == j) { 19 | i++; 20 | pmt[i-1] = 0; 21 | } else { 22 | j = pmt[j-1]; 23 | } 24 | } 25 | } 26 | 27 | return pmt; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /15.StrStr/pmt.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | // 如果一个字符串可以由一个子串重复构成,比如 3 | // AAAA 4 | // 那么前后缀的最长匹配为"AAA" 5 | // 那么s.length() - 这个最长匹配 6 | // 就是得到重复部分的长度 7 | // 构建PMT 8 | public int[] buildPMT(String sub) { 9 | final int N = sub == null ? 0 : sub.length(); 10 | 11 | int[] PMT = new int[N]; 12 | 13 | int i = 1; 14 | int j = 0; 15 | 16 | PMT[0] = 0; 17 | 18 | while (i < N) { 19 | if (sub.charAt(i) == sub.charAt(j)) { 20 | // 当相等的时候, 21 | i++; 22 | j++; 23 | PMT[i-1] = j; 24 | } else { 25 | if (0 == j) { 26 | // 如果匹配失败,并且j已经为0 27 | // 那么 28 | i++; 29 | PMT[i-1] = 0; 30 | } else { 31 | j = PMT[j-1]; 32 | } 33 | } 34 | } 35 | 36 | return PMT; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /15.StrStr/pmt.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def buildPMT(self, s): 3 | N = 0 if not s else len(s) 4 | pmt = [0] * N 5 | 6 | i = 1 7 | j = 0 8 | pmt[0] = 0 9 | 10 | while i < N: 11 | if s[i] == s[j]: 12 | i += 1 13 | j += 1 14 | pmt[i-1] = j 15 | else: 16 | if 0 == j: 17 | i += 1 18 | pmt[i-1] = 0 19 | else: 20 | j = pmt[j-1] 21 | 22 | return pmt 23 | -------------------------------------------------------------------------------- /17.Subset/78.子集.BFS.py: -------------------------------------------------------------------------------- 1 | # 2 | # @lc app=leetcode.cn id=78 lang=python 3 | # 4 | # [78] 子集 5 | # 6 | # https://leetcode-cn.com/problems/subsets/description/ 7 | # 8 | # algorithms 9 | # Medium (79.61%) 10 | # Likes: 1061 11 | # Dislikes: 0 12 | # Total Accepted: 212.1K 13 | # Total Submissions: 266.5K 14 | # Testcase Example: '[1,2,3]' 15 | # 16 | # 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。 17 | # 18 | # 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 19 | # 20 | # 21 | # 22 | # 示例 1: 23 | # 24 | # 25 | # 输入:nums = [1,2,3] 26 | # 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]] 27 | # 28 | # 29 | # 示例 2: 30 | # 31 | # 32 | # 输入:nums = [0] 33 | # 输出:[[],[0]] 34 | # 35 | # 36 | # 37 | # 38 | # 提示: 39 | # 40 | # 41 | # 1 42 | # -10 43 | # nums 中的所有元素 互不相同 44 | # 45 | # 46 | # 47 | 48 | # @lc code=start 49 | class Solution(object): 50 | def subsets(self, nums): 51 | """ 52 | :type nums: List[int] 53 | :rtype: List[List[int]] 54 | """ 55 | 56 | def clone(subset): 57 | ret = [] 58 | for x in subset: 59 | ret.append(x) 60 | return ret 61 | 62 | cur = [[]] 63 | 64 | for x in nums: 65 | curSize = len(cur) 66 | 67 | for i in range(curSize): 68 | ret = clone(cur[i]) 69 | ret.append(x) 70 | cur.append(ret) 71 | 72 | return cur 73 | # @lc code=end 74 | 75 | -------------------------------------------------------------------------------- /17.Subset/78.子集.binary.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=78 lang=cpp 3 | * 4 | * [78] 子集 5 | * 6 | * https://leetcode-cn.com/problems/subsets/description/ 7 | * 8 | * algorithms 9 | * Medium (79.61%) 10 | * Likes: 1061 11 | * Dislikes: 0 12 | * Total Accepted: 212.1K 13 | * Total Submissions: 266.5K 14 | * Testcase Example: '[1,2,3]' 15 | * 16 | * 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。 17 | * 18 | * 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 19 | * 20 | * 21 | * 22 | * 示例 1: 23 | * 24 | * 25 | * 输入:nums = [1,2,3] 26 | * 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]] 27 | * 28 | * 29 | * 示例 2: 30 | * 31 | * 32 | * 输入:nums = [0] 33 | * 输出:[[],[0]] 34 | * 35 | * 36 | * 37 | * 38 | * 提示: 39 | * 40 | * 41 | * 1 42 | * -10 43 | * nums 中的所有元素 互不相同 44 | * 45 | * 46 | */ 47 | 48 | // @lc code=start 49 | class Solution { 50 | public: 51 | vector> subsets(vector& nums) { 52 | const int N = nums.size(); 53 | 54 | vector> ans; 55 | 56 | for (int i = 0; i < (1< 0 and nums[i] == nums[i-1]: 51 | startPos = preBeforeUpdateSize 52 | 53 | for j in range(startPos, curSize): 54 | cur.append([x for x in cur[j]]) 55 | cur[-1].append(value) 56 | 57 | preBeforeUpdateSize = curSize 58 | 59 | return cur 60 | 61 | 62 | # @lc code=end 63 | 64 | -------------------------------------------------------------------------------- /19.Efforts/64.最小路径和.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=64 lang=java 3 | * 4 | * [64] 最小路径和 5 | * 6 | * https://leetcode-cn.com/problems/minimum-path-sum/description/ 7 | * 8 | * algorithms 9 | * Medium (68.34%) 10 | * Likes: 865 11 | * Dislikes: 0 12 | * Total Accepted: 209.9K 13 | * Total Submissions: 306.9K 14 | * Testcase Example: '[[1,3,1],[1,5,1],[4,2,1]]' 15 | * 16 | * 给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 17 | * 18 | * 说明:每次只能向下或者向右移动一步。 19 | * 20 | * 21 | * 22 | * 示例 1: 23 | * 24 | * 25 | * 输入:grid = [[1,3,1],[1,5,1],[4,2,1]] 26 | * 输出:7 27 | * 解释:因为路径 1→3→1→1→1 的总和最小。 28 | * 29 | * 30 | * 示例 2: 31 | * 32 | * 33 | * 输入:grid = [[1,2,3],[4,5,6]] 34 | * 输出:12 35 | * 36 | * 37 | * 38 | * 39 | * 提示: 40 | * 41 | * 42 | * m == grid.length 43 | * n == grid[i].length 44 | * 1 45 | * 0 46 | * 47 | * 48 | */ 49 | 50 | // @lc code=start 51 | class Solution { 52 | public int minPathSum(int[][] grid) { 53 | 54 | } 55 | } 56 | // @lc code=end 57 | 58 | -------------------------------------------------------------------------------- /20.Braces/22.括号生成.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=22 lang=java 3 | * 4 | * [22] 括号生成 5 | * 6 | * https://leetcode-cn.com/problems/generate-parentheses/description/ 7 | * 8 | * algorithms 9 | * Medium (77.09%) 10 | * Likes: 1756 11 | * Dislikes: 0 12 | * Total Accepted: 267K 13 | * Total Submissions: 346.4K 14 | * Testcase Example: '3' 15 | * 16 | * 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。 17 | * 18 | * 19 | * 20 | * 示例 1: 21 | * 22 | * 23 | * 输入:n = 3 24 | * 输出:["((()))","(()())","(())()","()(())","()()()"] 25 | * 26 | * 27 | * 示例 2: 28 | * 29 | * 30 | * 输入:n = 1 31 | * 输出:["()"] 32 | * 33 | * 34 | * 35 | * 36 | * 提示: 37 | * 38 | * 39 | * 1 40 | * 41 | * 42 | */ 43 | 44 | // @lc code=start 45 | class Solution { 46 | public List generateParenthesis(int n) { 47 | 48 | } 49 | } 50 | // @lc code=end 51 | 52 | -------------------------------------------------------------------------------- /21.Meets/903.cpp: -------------------------------------------------------------------------------- 1 | // https://www.lintcode.com/problem/903/description 2 | 3 | class Solution { 4 | public: 5 | /** 6 | * @param length: the length of the array 7 | * @param updates: update operations 8 | * @return: the modified array after all k operations were executed 9 | */ 10 | vector getModifiedArray(int length, vector> &updates) { 11 | // Write your code here 12 | vector A(length, 0/*value*/); 13 | 14 | for (auto &x: updates) { 15 | int startIndex = x[0]; 16 | int endIndex = x[1]; 17 | int value = x[2]; 18 | 19 | if (startIndex > endIndex) { 20 | continue; 21 | } 22 | 23 | // 如果超出数组的范围 24 | if (startIndex >= length) { 25 | continue; 26 | } 27 | // 当startIndex小于0的时候,就从0开始 28 | startIndex = std::max(startIndex, 0); 29 | A[startIndex] += value; 30 | 31 | // 如果超出数组的范围 32 | if (endIndex < 0) { 33 | continue; 34 | } 35 | 36 | if (endIndex + 1 < length) { 37 | A[endIndex + 1] -= value; 38 | } 39 | } 40 | 41 | int pre = 0; 42 | for (int i = 0; i < A.size(); i++) { 43 | pre += A[i]; 44 | A[i] = pre; 45 | } 46 | 47 | return A; 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /21.Meets/903.java: -------------------------------------------------------------------------------- 1 | // https://www.lintcode.com/problem/903/description 2 | 3 | public class Solution { 4 | /** 5 | * @param length: the length of the array 6 | * @param updates: update operations 7 | * @return: the modified array after all k operations were executed 8 | */ 9 | public int[] getModifiedArray(int length, int[][] updates) { 10 | // Write your code here 11 | int[] A = new int[length]; 12 | 13 | for (int i = 0; i < updates.length; i++) { 14 | int start = updates[i][0]; 15 | int end = updates[i][1]; 16 | int val = updates[i][2]; 17 | 18 | if (start > end) { 19 | continue; 20 | } 21 | 22 | if (0 <= start && start < length) { 23 | A[start] += val; 24 | } 25 | 26 | if (0 <= end && end + 1 < length) { 27 | A[end+1] -= val; 28 | } 29 | } 30 | 31 | int pre = 0; 32 | for (int i = 0; i < length; i++) { 33 | pre += A[i]; 34 | A[i] = pre; 35 | } 36 | 37 | return A; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /21.Meets/903.py: -------------------------------------------------------------------------------- 1 | # https://www.lintcode.com/problem/903/description 2 | 3 | class Solution: 4 | """ 5 | @param length: the length of the array 6 | @param updates: update operations 7 | @return: the modified array after all k operations were executed 8 | """ 9 | def get_modified_array(self, length, updates): 10 | # Write your code here 11 | A = [0] * length; 12 | for x in updates: 13 | startIndex = x[0] 14 | endIndex = x[1] 15 | value = x[2] 16 | 17 | if startIndex > endIndex: 18 | continue 19 | if startIndex >= length: 20 | continue 21 | if endIndex < 0: 22 | continue 23 | 24 | if startIndex < 0: 25 | startIndex = 0 26 | A[startIndex] += value 27 | 28 | if endIndex + 1 < length: 29 | A[endIndex + 1] -= value 30 | 31 | pre = 0 32 | for i in range(0, length): 33 | pre += A[i] 34 | A[i] = pre 35 | 36 | return A 37 | 38 | -------------------------------------------------------------------------------- /21.Meets/919.会议室II.差分2.java: -------------------------------------------------------------------------------- 1 | 2 | public class Solution { 3 | /** 4 | * @param intervals: an array of meeting time intervals 5 | * @return: the minimum number of conference rooms required 6 | */ 7 | public int minMeetingRooms(List intervals) { 8 | 9 | List item = new ArrayList<>(); 10 | for (Interval range: intervals) { 11 | item.add(range.start); 12 | item.add(0 - range.end); 13 | } 14 | 15 | Collections.sort(item, new Comparator() { 16 | public int compare(Integer a, Integer b) { 17 | return Math.abs(a) - Math.abs(b); 18 | } 19 | }); 20 | 21 | int ans = 0; 22 | int pre = 0; 23 | for (int i = 0; i < item.size(); i++) { 24 | if (item.get(i) >= 0) { 25 | pre++; 26 | } else { 27 | pre--; 28 | } 29 | ans = Math.max(ans, pre); 30 | } 31 | 32 | return ans; 33 | } 34 | } -------------------------------------------------------------------------------- /21.Meets/919.会议室II.差分3.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition of Interval: 3 | * public classs Interval { 4 | * int start, end; 5 | * Interval(int start, int end) { 6 | * this.start = start; 7 | * this.end = end; 8 | * } 9 | * } 10 | */ 11 | 12 | public class Solution { 13 | /** 14 | * @param intervals: an array of meeting time intervals 15 | * @return: the minimum number of conference rooms required 16 | */ 17 | public int minMeetingRooms(List intervals) { 18 | // Write your code here 19 | final int N = intervals == null ? 0 : intervals.size(); 20 | 21 | int[] start = new int[N]; 22 | int[] end = new int[N]; 23 | 24 | int i = 0; 25 | for (Interval range: intervals) { 26 | start[i] = range.start; 27 | end[i] = range.end; 28 | i++; 29 | } 30 | 31 | Arrays.sort(start); 32 | Arrays.sort(end); 33 | 34 | i = 0; 35 | int j = 0; 36 | 37 | int pre = 0; 38 | int ans = 0; 39 | while (i < N || j < N) { 40 | if (j >= N || i < N && start[i] < end[j]) { 41 | // 是个坐标的起始点 42 | pre++; 43 | i++; 44 | } else { 45 | // 是个坐标的终点 46 | pre--; 47 | j++; 48 | } 49 | ans = Math.max(ans, pre); 50 | } 51 | 52 | return ans; 53 | } 54 | } -------------------------------------------------------------------------------- /21.Meets/ans.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lagoueduCol/Algorithm-Dryad/c11331df1eadb8fbcdf3ae5615eb5ddc9b4c414c/21.Meets/ans.java -------------------------------------------------------------------------------- /22.DS/946.验证栈序列.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=946 lang=java 3 | * 4 | * [946] 验证栈序列 5 | * 6 | * https://leetcode-cn.com/problems/validate-stack-sequences/description/ 7 | * 8 | * algorithms 9 | * Medium (61.43%) 10 | * Likes: 178 11 | * Dislikes: 0 12 | * Total Accepted: 22.4K 13 | * Total Submissions: 36.4K 14 | * Testcase Example: '[1,2,3,4,5]\n[4,5,3,2,1]' 15 | * 16 | * 给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 17 | * 操作序列的结果时,返回 true;否则,返回 false 。 18 | * 19 | * 20 | * 21 | * 示例 1: 22 | * 23 | * 输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1] 24 | * 输出:true 25 | * 解释:我们可以按以下顺序执行: 26 | * push(1), push(2), push(3), push(4), pop() -> 4, 27 | * push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1 28 | * 29 | * 30 | * 示例 2: 31 | * 32 | * 输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2] 33 | * 输出:false 34 | * 解释:1 不能在 2 之前弹出。 35 | * 36 | * 37 | * 38 | * 39 | * 提示: 40 | * 41 | * 42 | * 0 <= pushed.length == popped.length <= 1000 43 | * 0 <= pushed[i], popped[i] < 1000 44 | * pushed 是 popped 的排列。 45 | * 46 | * 47 | */ 48 | 49 | // @lc code=start 50 | class Solution { 51 | public boolean validateStackSequences(int[] pushed, int[] popped) { 52 | 53 | } 54 | } 55 | // @lc code=end 56 | 57 | -------------------------------------------------------------------------------- /24.MyInterView/136.只出现一次的数字.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=136 lang=java 3 | * 4 | * [136] 只出现一次的数字 5 | * 6 | * https://leetcode-cn.com/problems/single-number/description/ 7 | * 8 | * algorithms 9 | * Easy (70.74%) 10 | * Likes: 1674 11 | * Dislikes: 0 12 | * Total Accepted: 326.1K 13 | * Total Submissions: 461K 14 | * Testcase Example: '[2,2,1]' 15 | * 16 | * 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 17 | * 18 | * 说明: 19 | * 20 | * 你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗? 21 | * 22 | * 示例 1: 23 | * 24 | * 输入: [2,2,1] 25 | * 输出: 1 26 | * 27 | * 28 | * 示例 2: 29 | * 30 | * 输入: [4,1,2,1,2] 31 | * 输出: 4 32 | * 33 | */ 34 | 35 | // @lc code=start 36 | class Solution { 37 | public int singleNumber(int[] nums) { 38 | int ans = 0; 39 | for (int x: nums) { 40 | ans ^= x; 41 | } 42 | return ans; 43 | } 44 | } 45 | // @lc code=end 46 | 47 | -------------------------------------------------------------------------------- /24.MyInterView/137.只出现一次的数字-ii.2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=137 lang=java 3 | * 4 | * [137] 只出现一次的数字 II 5 | * 6 | * https://leetcode-cn.com/problems/single-number-ii/description/ 7 | * 8 | * algorithms 9 | * Medium (68.50%) 10 | * Likes: 498 11 | * Dislikes: 0 12 | * Total Accepted: 49.5K 13 | * Total Submissions: 72.3K 14 | * Testcase Example: '[2,2,3,2]' 15 | * 16 | * 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。 17 | * 18 | * 说明: 19 | * 20 | * 你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗? 21 | * 22 | * 示例 1: 23 | * 24 | * 输入: [2,2,3,2] 25 | * 输出: 3 26 | * 27 | * 28 | * 示例 2: 29 | * 30 | * 输入: [0,1,0,1,0,1,99] 31 | * 输出: 99 32 | * 33 | */ 34 | 35 | // @lc code=start 36 | 37 | class Solution { 38 | public int singleNumber(int[] nums) { 39 | int ones = 0, twos = 0; 40 | for(int num : nums){ 41 | ones = ones ^ num & ~twos; 42 | twos = twos ^ num & ~ones; 43 | } 44 | return ones; 45 | } 46 | } 47 | 48 | // @lc code=end 49 | 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LaGouAlgo 2 | Algorithms for LaGou 3 | -------------------------------------------------------------------------------- /genurl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | echo https://github.com/lagoueduCol/Algorithm-Dryad/blob/main/${1} 5 | -------------------------------------------------------------------------------- /remove_comment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for n in `find . -name "*.py"`; do sed -i "" "/@lc/d" $n; done 4 | for n in `find . -name "*.java"`; do sed -i "" "/@lc/d" $n; done 5 | for n in `find . -name "*.cpp"`; do sed -i "" "/@lc/d" $n; done 6 | 7 | --------------------------------------------------------------------------------