LeetCode 797. 所有可能的路径(dfs) / 881. 救生艇(双指针,贪心) / 295. 数据流的中位数(对顶堆)
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 797. 所有可能的路径(dfs) / 881. 救生艇(双指针,贪心) / 295. 数据流的中位数(对顶堆)相关的知识,希望对你有一定的参考价值。
797. 所有可能的路径
2021.8.25 每日一题
题目描述
给你一个有 n 个节点的 有向无环图(DAG),请你找出所有从节点 0 到节点 n-1 的路径并输出(不要求按特定顺序)
二维数组的第 i 个数组中的单元都表示有向图中 i 号节点所能到达的下一些节点,空就是没有下一个结点了。
译者注:有向图是有方向的,即规定了 a→b 你就不能从 b→a 。
示例 1:
输入:graph = [[1,2],[3],[3],[]]
输出:[[0,1,3],[0,2,3]]
解释:有两条路径 0 -> 1 -> 3 和 0 -> 2 -> 3
示例 2:
输入:graph = [[4,3,1],[3,2,4],[3],[4],[]]
输出:[[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,4]]
示例 3:
输入:graph = [[1],[]]
输出:[[0,1]]
示例 4:
输入:graph = [[1,2,3],[2],[3],[]]
输出:[[0,1,2,3],[0,2,3],[0,3]]
示例 5:
输入:graph = [[1,3],[2],[3],[]]
输出:[[0,1,2,3],[0,3]]
提示:
n == graph.length
2 <= n <= 15
0 <= graph[i][j] < n
graph[i][j] != i(即,不存在自环)
graph[i] 中的所有元素 互不相同
保证输入为 有向无环图(DAG)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/all-paths-from-source-to-target
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
常规回溯问题,无环图,不需要记录已遍历过的点
class Solution {
List<List<Integer>> res = new ArrayList<>();
int n;
public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
n = graph.length;
List<Integer> list = new ArrayList<>();
list.add(0);
dfs(0, list, graph);
return res;
}
public void dfs(int k, List<Integer> list, int[][] graph){
if(k == n - 1){
res.add(new ArrayList<>(list));
return;
}
int[] pos = graph[k];
for(int i = 0; i < pos.length; i++){
int p = pos[i];
list.add(p);
dfs(p, list, graph);
list.remove(list.size() - 1);
}
}
}
881. 救生艇
2021.8.226 每日一题
题目描述
第 i 个人的体重为 people[i],每艘船可以承载的最大重量为 limit。
每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit。
返回载到每一个人所需的最小船数。(保证每个人都能被船载)。
示例 1:
输入:people = [1,2], limit = 3
输出:1
解释:1 艘船载 (1, 2)
示例 2:
输入:people = [3,2,2,1], limit = 3
输出:3
解释:3 艘船分别载 (1, 2), (2) 和 (3)
示例 3:
输入:people = [3,5,3,4], limit = 5
输出:4
解释:4 艘船分别载 (3), (3), (4), (5)
提示:
1 <= people.length <= 50000
1 <= people[i] <= limit <= 30000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/boats-to-save-people
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
双指针
class Solution {
public int numRescueBoats(int[] people, int limit) {
//双指针
int l = people.length;
int left = 0;
int right = l - 1;
int count = 0;
Arrays.sort(people);
while(left <= right){
while(left <= right && people[left] + people[right] > limit){
right--;
count++;
}
while(left <= right && people[left] + people[right] <= limit){
left++;
right--;
count++;
}
}
return count;
}
}
295. 数据流的中位数
2021.8.27 每日一题
题目描述
中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。
例如,
[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:
void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。
示例:
addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2
进阶:
如果数据流中所有整数都在 0 到 100 范围内,你将如何优化你的算法?
如果数据流中 99% 的整数都在 0 到 100 范围内,你将如何优化你的算法?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-median-from-data-stream
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
对顶堆,保持两个堆平衡,然后用堆顶的数来求出中位数
存放的时候,先入大根堆,然后根据两个堆容量的大小和堆顶元素大小来判断如何进行调整
class MedianFinder {
PriorityQueue<Integer> min; //小根堆放大数
PriorityQueue<Integer> max; //大根堆放小数
int n;
/** initialize your data structure here. */
public MedianFinder() {
min = new PriorityQueue<>();
max = new PriorityQueue<>((a, b) -> (b - a));
n = 0;
}
public void addNum(int num) {
//规定小顶堆的数量大于等于大顶堆
//先放到大顶堆里,再调整
n++;
max.offer(num);
if(max.size() > min.size())
min.offer(max.poll());
else if(max.peek() > min.peek()){
min.offer(max.poll());
max.offer(min.poll());
}
}
public double findMedian() {
if(n % 2 == 0)
return (min.peek() + max.peek()) / 2.0;
else
return min.peek();
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
以上是关于LeetCode 797. 所有可能的路径(dfs) / 881. 救生艇(双指针,贪心) / 295. 数据流的中位数(对顶堆)的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode Algorithm 797. 所有可能的路径
LeetCode Algorithm 797. 所有可能的路径
[Mdfs] lc797. 所有可能的路径(图遍历+dfs易错点+知识理解)