leetcode图相关基础题目

本文主要探讨LeetCode中涉及图的算法题目,包括宽度优先遍历(BFS)、最小生成树(Kruskal & Prim)以及单源最短路径(Dijkstra)的应用,通过实例解析如何解决二叉树问题及构建最小费用网络。
摘要由CSDN通过智能技术生成

leetcode图相关基础题目

左神图模板

作用: 熟悉这套模板,在作图相关题目时自己写一个接口将题目所给的数据结构转化为图对象,再使用该数据结构完成算法。

// 结点
class Node {
   
	int value; // 结点的编号或值,不同题目灵活应变
	int in; // 入度
	int out; // 出度
	ArrayList<Node> nexts; // 从该结点出发连向的其他结点
	ArrayList<Edge> edges; // 该结点出所形成的边
	public Node (int value) {
   
		this.value = value;
		in = 0;
		 out = 0;
		 nexts = new ArrayList<>();
		 edges = new ArrayList<>();
	}
}

// 边
class Edge {
   
	int weight; // 边的权重,根据题目灵活变动
	Node from; // 这条边的起始结点
	Node to;	// 这条边的终止结点
	public Edge(int weight, Node from, Node to) {
   
		this.weight = weight;
		this.from = from;
		this.to = to;
	}
}

// 图
class Graph {
   
	HashsMap<Integer, Node> nodes; // 图中所有的结点
	HashSet<Edge> edges; // 图中所有的边
	public Graph() {
   
		nodes = new HashMap<>();
		edges = new HashSet<>();
	}
}

leetcode 863. 二叉树中所有距离为 K 的结点

给定一个二叉树(具有根结点 root), 一个目标结点 target ,和一个整数值 k 。

返回到目标结点 target 距离为 k 的所有结点的值的列表。 答案可以以 任何顺序 返回。
思路: 使用图的宽度优先遍历(BFS)。先将题目中的数据结构转化为熟悉的图结构,找到目标结点,从目标节点开始出发对图进行宽度优先遍历,在遍历过程中需要记录当是在第几层,这里采用了二叉树层序遍历的技巧,使用curEnd记录当前层的最后一个结点,nextEnd记录下一层的最后一个结点,以此来判断目前是在哪一层,当在第k层时,将该层的节点记录到结果集中。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
   
    public List<Integer> distanceK(TreeNode root, TreeNode target, int k) {
   
        List<Integer> res = new ArrayList<>();
        Graph graph = new Graph();
        createGraph(root, graph);
        // BFS
        Queue<Node> queue = new LinkedList<>();
        Set<Node> set = new HashSet<>();
        Node node = graph.nodes.get(target.val);
        if (node == null) return res;
        queue.add(node);
        set.add(node);
        int step = 0;
        Node curEnd = node;
        Node nextEnd = null;
        while (!queue.isEmpty()) {
   
            Node cur = queue.poll();
            if (step == k) res.add(cur.value);
            for (Node next : cur.nexts) {
   
                if (!set.contains(next)) {
   
                    queue.add(next);
                    set.add(next);
                    nextEnd = next;
                }
            }

            if (cur == curEnd) {
   
                step++;
                curEnd = nextEnd;
                nextEnd = null;
            }
        }

        return res;
    }

    public List<Integer> distanceK2(TreeNode root, TreeNode target, int k) {
   
        List<Integer> res = new ArrayList<>();
        Graph graph = new Graph();
        createGraph(root, graph);
        // DFS 未成功
        Stack<Node> stack = new Stack<>();
        Set<Node> set = new HashSet<>();
        Node node = graph.nodes.get(target.val);
        stack.add(node);
        set.add(node);
        while (!stack.isEmpty()) {
   
            Node cur = stack.pop();
            // res.add(cur.value);
            for (Node next : cur.nexts) {
   
                if (!set.contains(next)) {
   
                    stack.add(cur);
                    stack.add(next);
                    set.add(next);
                    res.add(next.value);
                    break;
                }
            }
        }
        return res;
    }

    // 将二叉树转化为图
    public void createGraph(TreeNode root, Graph graph) {
   
        if (root == null) return;
        Integer from = root.val;
        if (!graph.nodes.containsKey(from)) {
   
            graph.nodes.put(from, new Node(from));
        }
        Node fromNode = graph.nodes.get(from);
        if (root.left != null) {
   
            int toLeft = root.left.val;
            if (!graph.nodes.containsKey(toLeft)) {
   
                graph.nodes.put(toLeft, new Node(toLeft));
            }
            Node toLeftNode = graph.nodes.get(toLeft);
            Edge leftEdge1 = new Edge(0, fromNode, toLeftNode); 
            Edge leftEdge2 = new Edge(0, toLeftNode, fromNode); 
            fromNode.nexts.add(toLeftNode);
            toLeftNode.nexts.add(fromNode);
            fromNode.out++;
            fromNode.in++;
            toLeftNode.out++;
            toLeftNode.in++;
            fromNode.edges.add(leftEdge1);
            toLeftNode.edges.add(leftEdge2);
            graph.edges.add(leftEdge1);
            graph.edges.add(leftEdge2);
        }
        if (root.right != null) {
   
            int toRight = root.right.val;
            if (!graph.nodes.containsKey(toRight)) {
   
                graph.nodes.put(toRight, new Node(toRight));
            }
            Node toRightNode = graph.nodes.get(toRight);
            Edge rightEdge1 = new Edge(0, fromNode, toRightNode); 
            Edge rightEdge2 = new Edge(0, toRightNode, fromNode); 
            fromNode.nexts.add(toRightNode);
            toRightNode.nexts.add(fromNode);
            fromNode.out++;
            fromNode.in++;
            toRightNode.out++;
            toRightNode.in++;
            fromNode.edges.add(rightEdge1);
            toRightNode.edges.add(rightEdge2);
            graph.edges.add(rightEdge1);
            graph.edges.add(rightEdge2);
        }
        createGraph(root.left, graph);
        createGraph(root.right, graph);
    }
}

class Node {
   
    int value;
    int in;
    int out;
    ArrayList<Node> nexts;
    ArrayList<Edge> edges;
    int step;

    public Node(int value) {
   
        this.value = value;
        in = 0;
        out = 0;
        step = 0;
        nexts = new ArrayList<>();
        edges = new ArrayList<>();
    }

    public void setStep(int s) {
   
        step = s;
    }
}

class Edge {
   
    int weight;
    Node from;
    Node to;

    public Edge(int weight, Node from, Node to) {
   
        this.weight = weight;
        this.from = from;
        this.to = to;
    }
}

class Graph {
   
    HashMap<Integer, Node> nodes;
    HashSet<Edge> edges;

    public Graph() {
   
        nodes = new HashMap<>();
        edges = new HashSet<>();
    }
}

leetcode 207. 课程表

你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。

在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。

例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。

class Solution {
   
    public boolean canFinish<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值