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易错点+知识理解)

[Mdfs] lc797. 所有可能的路径(图遍历+dfs易错点+知识理解)

LeetCode 797. 所有可能的路径

LeetCode 797. 所有可能的路径