LeetCode 261. Graph Valid Tree(判断图是否为树)

LeetCode 261. Graph Valid Tree - 彻底掌握并查集(Union Find)系列题17 ​ 这题跟LeetCode 684. Redundant Connection几乎一样,同一类题刷来刷去解法都大同小异。 题目问一个无向图是否是一棵有效树,只要知道形成有效树的条件,这道题就变得很容易了。 ​ 阅读详情

原题网址:https://leetcode.com/problems/graph-valid-tree/

Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.

For example:

Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return true.

Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], return false.

Hint:

  1. Given n = 5 and edges = [[0, 1], [1, 2], [3, 4]], what should your return? Is this case a valid tree?
  2. According to the definition of tree on Wikipedia: “a tree is an undirected graph in which any two vertices are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.”

注意,这里的树是普通的树,不是二叉树!

思路:要判断一个图是否为树,首先要知道树的定义。

一棵树必须具备如下特性:

(1)是一个全连通图(所有节点相通)

(2)无回路

其中(2)等价于:(3)图的边数=节点数-1

因此我们可以利用特性(1)(2)或者(1)(3)来判断。


方法一:广度优先搜索。要判断连通性,广度优先搜索法是一个天然的选择,时间复杂度O(n),空间复杂度O(n)。

public class Solution {
    public boolean validTree(int n, int[][] edges) {
        Map<Integer, Set<Integer>> graph = new HashMap<>();
        for(int i=0; i<edges.length; i++) {
            for(int j=0; j<2; j++) {
                Set<Integer> pairs = graph.get(edges[i][j]);
                if (pairs == null) {
                    pairs = new HashSet<>();
                    graph.put(edges[i][j], pairs);
                }
                pairs.add(edges[i][1-j]);
            }
        }
        Set<Integer> visited = new HashSet<>();
        Set<Integer> current = new HashSet<>();
        visited.add(0);
        current.add(0);
        while (!current.isEmpty()) {
            Set<Integer> next = new HashSet<>();
            for(Integer node: current) {
                Set<Integer> pairs = graph.get(node);
                if (pairs == null) continue;
                for(Integer pair: pairs) {
                    if (visited.contains(pair)) return false;
                    next.add(pair);
                    visited.add(pair);
                    graph.get(pair).remove(node);
                }
            }
            current = next;
        }
        return visited.size() == n;
    }
}

方法二:深度优先搜索,搜索目标是遍历全部节点。参考文章:http://buttercola.blogspot.com/2015/08/leetcode-graph-valid-tree.html

public class Solution {
    private boolean[] visited;
    private int visits = 0;
    private boolean isTree = true;
    private void check(int prev, int curr, List<Integer>[] graph) {
        if (!isTree) return;
        if (visited[curr]) {
            isTree = false;
            return;
        }
        visited[curr] = true;
        visits ++;
        for(int next: graph[curr]) {
            if (next == prev) continue;
            check(curr, next, graph);
            if (!isTree) return;
        }
        
    }
    public boolean validTree(int n, int[][] edges) {
        visited = new boolean[n];
        List<Integer>[] graph = new List[n];
        for(int i=0; i<n; i++) graph[i] = new ArrayList<>();
        for(int[] edge: edges) {
            graph[edge[0]].add(edge[1]);
            graph[edge[1]].add(edge[0]);
        }
        check(-1, 0, graph);
        return isTree && visits == n;
    }
}


方法三:按节点大小对边进行排序,原理类似并查集。

public class Solution {
    public boolean validTree(int n, int[][] edges) {
        if (edges.length != n-1) return false;
        Arrays.sort(edges, new Comparator<int[]>() {
           @Override
           public int compare(int[] e1, int[] e2) {
               return e1[0] - e2[0];
           }
        });
        int[] sets = new int[n];
        for(int i=0; i<n; i++) sets[i] = i;
        for(int i=0; i<edges.length; i++) {
            if (sets[edges[i][0]] == sets[edges[i][1]]) return false;
            if (sets[edges[i][0]] == 0) {
                sets[edges[i][1]] = 0;
            } else if (sets[edges[i][1]] == 0) {
                sets[edges[i][0]] = 0;
            } else {
                sets[edges[i][1]] = sets[edges[i][0]];
            }
        }
        return true;
    }
}

方法四:Union-Find

public class Solution {
    public boolean validTree(int n, int[][] edges) {
        if (edges.length != n-1) return false;
        int[] roots = new int[n];
        for(int i=0; i<n; i++) roots[i] = i;
        for(int i=0; i<edges.length; i++) {
            int root1 = root(roots, edges[i][0]);
            int root2 = root(roots, edges[i][1]);
            if (root1 == root2) return false;
            roots[root2] = root1;
        }
        return true;
    }
    private int root(int[] roots, int id) {
        if (id == roots[id]) return id;
        return root(roots, roots[id]);
    }
}

参考文章:

http://blog.youkuaiyun.com/dm_vincent/article/details/7655764

http://www.elvisyu.com/graph-valid-tree-union-and-find/

http://blog.youkuaiyun.com/pointbreak1/article/details/48796691

http://buttercola.blogspot.com/2015/08/leetcode-graph-valid-tree.html

【单片机】STM32F103C8T6 最小系统板原理图 STM32F103C8T6是一款基于ARM Cortex-M3内核的32位微控制器,由STMicroelectronics(ST)公司生产。它是STMicroelectronics的STM32系列微控制器中的一员,被广泛应用于嵌入式系统和电子设备中。LQFP48封装(Low-profile Quad Flat Package,48引脚)SRAM(静态随机访问存储器):20 KB。支持JTAG调试和编程接口(可选)多个通用输入/输出口(GPIO)USB接口(用于USB设备模式)内置调试和编程接口(SWD) 阅读详情

相关推荐

基于E310的纯逻辑代码实现AD9361射频收发

基于微相科技的E310平台实现AD9361的射频收发功能。采用纯逻辑控制的方式,不需要PS参与。实现了用VIO控制收发使能,发射功率,收发频率,数据接口时序控制,接收增益,BIST测试等功能。

xiaomingzi55的博客 2331

判断一个图是否是树

判断一个图是否是树 Alogrithm: 如果无向图具有以下性质,则它是树。 没有环 图是连通的 对于无向图,我们可以使用BFS或DFS来检测以上两个性质: 如何检测无向图中的环? 我们可以使用 BFS 或 DFS。对于每个访问过的顶点 ‘v’,如果有一个相邻的 ‘u’ 使得 u 已经被访问过并且 u 不是 v 的父节点,那么图中存在一个环。如果没有为任何顶点找到这样的相邻点,我们就说没有环,参考在一个无向图中找环。 如何检查连通性? 由于图是无向图,我们可以从任何顶点开始BFS或DF

wat1r的博客 5552

模拟波束赋形 vs 数字波束赋形:5G天线设计中的成本与性能权衡

本文深入剖析了5G天线设计中模拟波束赋形与数字波束赋形的核心差异,重点探讨了二者在硬件成本、功耗、网络覆盖能力和频谱效率等方面的权衡。文章指出,模拟方案成本低但灵活性有限,数字方案性能强大但代价高昂,而混合波束赋形已成为主流折中方案。决策需紧密结合具体的部署场景、性能要求和总拥有成本进行综合考量。

weixin_28432777的博客 840

判断图是否构成树(和大家可能不太一样的方法)

关于一个给出结点数和详细的边的图能否构成树的判断问题

weixin_62126667的博客 1436

SRA数据库

简介 序列读取存档(sequence Read Archive,SRA)数据是可通过多个云提供商和NCBI服务器获得的,它是最大的可公开获得的高通量测序数据存储库。 SRA接受来自生活各个部门以及宏基因组学和环境调查的数据。 SRA存储原始测序数据和比对信息,以提高可重复性并通过数据分析促进新发现。 NCBI网站储存二代测序原始数据的数据库 SRA官网 从Entrez搜索结果中下载SRA序列 例如查找SRA Entrez中BALB / c小鼠淋巴结组织的RNA-Seq记录 获取搜索结果 SRA se

qq_44520665的博客 5914

直线电机驱动技术原理与应用解析

直线电机作为直接电能-直线运动转换装置,其核心原理基于电磁感应定律和洛伦兹力公式。通过三相交流电在定子绕组中产生行波磁场,与动子永磁体相互作用实现精准推力控制。相比传统旋转电机传动系统,直线电机具有零传动间隙、高动态响应(加速度可达10g)和微米级定位精度等技术优势,这使其成为半导体光刻机、精密数控机床等高端装备的关键驱动部件。现代直线电机驱动单元通常采用三环控制架构(电流环、速度环、位置环),配合SiC功率器件和高分辨率光栅反馈,实现纳米级运动控制。随着模块化设计和直接冷却技术的发展,直线电机正朝着更高功

weixin_26802933的博客 259

如何判断无向图是否为树

一个无向图是一棵树的条件是:G必须是无回路的连通图或者有n-1条边的连通图。 对连通的判定:用能否全部遍历所有顶点来实现。 本算法中采用深度优先搜索算法在遍历图的过程中统计可能访问到的顶点个数和边的条数。若一次就遍历访问到N个顶点和n-1条边。则为一棵树。 bool isTree(Graph &G){ for(i=1;i<G.vexnum;i++) visited[i]=FALSE; int vNum=0,eNum=0; ...

qq_45419640的博客 4261

YOLOv13-SWC (ShiftWise Convolution) 完整移植与原理深度解析教程

YOLOv13-SWC模型移植与原理解析 本文详细介绍了YOLOv13-SWC模型的完整移植过程与核心技术原理。YOLOv13-SWC在YOLOv8架构基础上引入ShiftWise Convolution(SWC)模块,通过创新性的位移操作、重参数化大核卷积和LoRA分解技术,显著提升了模型性能。文章包含三个核心部分: 模型移植实现:包括配置文件创建、任务模块修改和核心代码实现,重点介绍了SWC模块的掩码机制和LoRA卷积分解策略。 ShiftWise操作原理:深入解析了将大核卷积分解为小核卷积位移组合的数

FJN110的博客 504

Leetcode 261.以图判树

Time: 20190903 Type: Medium 题目描述 给定从 0 到 n-1 标号的 n 个结点,和一个无向边列表(每条边以结点对来表示),请编写一个函数用来判断这些边是否能够形成一个合法有效的树结构。 示例 1: 输入: n = 5, 边列表 edges = [[0,1], [0,2], [0,3], [1,4]] 输出: true 示例 2: 输入: n = 5, 边列表 edge...

Bing's Blog 7722

华为OD机试真题 新系统2026-04-01 Python&JS【计算数列位置N的值】

如果其前面的M个元素中,存在值相同的元素,则该位置上的数值等于前面M个数中最大的数值与最小的数值之如果其前面的M个元素中,不存在值相同的元素,则该位置上的数值等于前面M个数中最大的数值与最小的数值之差;1、输入M、N两个数,则按照以下规则形成一个数列;两个整数,用逗号分割,分别表示M和N。一个整数,表示数列第N个位置上的数值。2、数列的前M个元素的值为1到M;请计算该数列第N个位置上的数值。N取值范围:1<= N<=50。M取值范围:3<=M<=10。

MISAYAONE的博客 3235

WiFi偏门协议(四):增强的传输机制802.11aa

区分Unicast和Multicast的优先级,以及设定不同的重传次数,以细化EDCA机制。 SCS(StreamClassification Service) 如上图,在VI,VO内各自又增加了一个queue, 对应不同的MAC header。VI和VO内的两个queue可以分别对应UC和MC。这样就提供了同一个AC内的更细粒度的优先级区分。当然还可以使用Drop Eligibility Indication子域来区分不同的重传次数。 改善Multicast数据传...

reekyli的专栏 1790

LeetCode--以图判树(Python)

题目描述 给定从 0 到 n-1 标号的 n 个结点,和一个无向边列表(每条边以结点对来表示),请编写一个函数用来判断这些边是否能够形成一个合法有效的树结构。 示例 1: 输入: n = 5, 边列表 edges = [[0,1], [0,2], [0,3], [1,4]] 输出: true 示例 2: 输入: n = 5, 边列表 edges = [[0,1], [1,2], [2,3], [1,3], [1,4]] 输出: false 注意:你可以假定边列表 edges 中不会出现重复的边。由于所

qq_33316931的博客 844

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

【LeetCode】261. Graph Valid Tree(判断图是否为树)

Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree. For example: Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return true.

森森猪的博客 641

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

[leetcode] 261. Graph Valid Tree 解题报告

题目链接:https://leetcode.com/problems/graph-valid-tree/ Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these

小榕流光的专栏 4546

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Leetcode 261. Graph Valid Tree(python)

Leetcode 261. Graph Valid Tree题目解法1:DFS解法2:BFS解法3:并查集(union find)参考链接: 题目 Given n nodes labeled from 0 to n-1 and a list of undirected edges (each edge is a pair of nodes), write a function to check w...

qq_37821701的博客 2020

[LeetCode 261] Graph Valid Tree

Givennnodes labeled from0ton - 1and a list ofundirectededges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree. Example Example 1: Input: n...

ExcitedZhang的博客 906

[Leetcode] 261. Graph Valid Tree 解题报告

题目: Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree. For example: G

魔豆(Magicbean)的博客 1204

Leetcode 261 Graph Valid Tree

Given n nodes labeled from 0 to n-1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree. Input: n = 5, and edges = [[0,1],...

Tech in Pieces 415

[leetcode] 261. Graph Valid Tree

valid tree: = 无向图+无环+只一个连通分量 Solution 1 : BFS 思路参考: 算法1: 我们知道对于环 1-2-3-4-1,每个节点的度都是2,基于此我们有如下算法(这是类似于有向图的拓扑排序): 求出图中所有顶点的度 删除图中所有度 <=1 的顶点以及与该顶点相关的边,把与这些边相关的顶点的度减一 如果还有度<=1的顶点重复步骤2 最后如果还存在未被删除的顶...

Belle_Chou的博客 421

[Leetcode] 261. Graph Valid Tree

这题本质并不复杂, 只是操作起来略烦和需要小心 一个图是否为树,判断条件有二:1.是否存在环。2.是否0 ~ n - 1这n个点都被走完了,也就是木有orphan nodes 所以整个流程基本就是:根据输入建图,然后遍历图找环,无环而且走过的节点数为n即是树。 构图的方式很多种,可以自己开一个class。如果懒得这么做,一般用哈希表也可以HashMap&lt;Integer(父亲节点),Ha......

chaochen1407的专栏 909

LeetCode #261. Graph Valid Tree

题目描述: Givennnodes labeled from0ton-1and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree. Example 1: Input: n = ...

LawFile的博客 257

【Leetcode】261. Graph Valid Tree

基本思想是这样的,构造一个并查集,每次遍历一条边的时候先查一下两个顶点是否已经属于同一个集合了,如果是,那就说明有环。一个图是一棵树当且仅当其顶点数等于边数加。

数学、算法爱好者的博客 777

Leetcode - 261. Graph Valid Tree

Problem description: Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.For example

Tigers Den 564

[Swift]LeetCode261.图验证树 $ Graph Valid Tree

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)➤GitHub地址:https://github.com/strengthen/LeetCode➤原文地址:https://www.cnblogs.com/streng...

weixin_30639719的博客 303

LeetCode 261. Graph Valid Tree

DFS https://www.geeksforgeeks.org/check-given-graph-tree/ 判断一个Graph是否为Tree有两个条件:1) 连通图 2) 没有环 这道题是无向图,判断有没有环可以dfs来做,比有向图容易很多。 dfs判断图是否有环:Detect Cycle In Directed/Undirected Graph 判断是否是连通图很容易,在df...

weixin_34209406的博客 257
上一篇: LeetCode 260. Single Number III
下一篇: LeetCode 263. Ugly Number(丑数字)
jmspan
博客等级 码龄11年 99粉丝 431原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值