2020.1012.-2020.10.17 leetcode刷题总结(树&图)


一.题目列表
1.翻转二叉树
题目描述:
翻转一棵二叉树。

示例:
输入:
4
/
2 7
/ \ /
1 3 6 9
输出:
4
/
7 2
/ \ /
9 6 3 1

题解:
递归

2.二叉搜索树的最近公共祖先
题目描述:
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

示例:
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。

题解:
法一:因为是搜索二叉树,root与q p的差的值为同号时,将root赋值为其左子树或者右子树,若异号则返回root
法二:设置一个hashmap存储每个结点及其父节点,循环进行层次遍历直到两个节点都找到其父节点。设置一个集合存储p节点及其所有祖先节点,然后判断q节点是否在这个集合中,q=q.parents 返回该节点

3.不同的二叉搜索树 II
题目描述:
给定一个整数 n,生成所有由 1 … n 为节点所组成的 二叉搜索树 。

示例:
输入:3
输出:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
解释:
以上的输出对应以下 5 种不同结构的二叉搜索树:
1 3 3 2 1
\ / / / \
3 2 1 1 3 2
/ / \
2 1 2 3

题解:
定义一个List<TreeNode 如果n=0
返回一个空list 否则记录开始和结束位置,进行循环,左子树等与迭代start-----i-1 右子树等于迭代i+1------end 然后在左右子树中各选一个加入该节点的左右子树 将该节点加入list

4.另一个树的子树
题目描述:
给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。

示例:
示例 1:
给定的树 s:
3
/
4 5
/
1 2
给定的树 t:
4
/
1 2
返回 true,因为 t 与 s 的一个子树拥有相同的结构和节点值。

题解:
定义一个issame函数判断两颗树是否相同

5.二叉搜索树中第K小的元素
题目描述:
给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。

示例:
输入: root = [3,1,4,null,2], k = 1
3
/
1 4

2
输出: 1

题解:
法一:中序遍历一棵树,返回第k-1个数
法二:定义一个栈,一次把root和其左子树放入,root=栈顶,若k–=0,则返回root,否则root=root.right

6.路径总和 III
题目描述:
给定一个二叉树,它的每个结点都存放着一个整数值。
找出路径和等于给定数值的路径总数。
路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。

示例:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
10
/
5 -3
/ \
3 2 11
/ \
3 -2 1
返回 3。和等于 8 的路径有:

  1. 5 -> 3
  2. 5 -> 2 -> 1
  3. -3 -> 11

题解:
设置一个list记录当前该层的结点值,若temp==sum则数目+1,返回该数目和左节点的数目+右节点的数目

7.二叉搜索树中的搜索
题目描述:
给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。

示例:
给定二叉搜索树:
4
/
2 7
/
1 3
和值: 2
你应该返回如下子树:
2
/ \
1 3

题解:

8.二叉树的后序遍历
题目描述:
给定一个二叉树,返回它的 后序 遍历。

示例:
输入: [1,null,2,3]
1

2
/
3
输出: [3,2,1]

题解:

9.从先序遍历还原二叉树
题目描述:
我们从二叉树的根节点 root 开始进行深度优先搜索。
在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度),然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1。根节点的深度为 0)。
如果节点只有一个子节点,那么保证该子节点为左子节点。
给出遍历输出 S,还原树并返回其根节点 root。

示例:

输入:“1-2–3--4-5–6--7”
输出:[1,2,5,3,4,6,7]

题解:
定义一个栈,获取当前level,和当前val,如果栈顶的左子树为空,则左子树为该val,否则右子树为该val,并将该node入栈,最后返回栈底元素


一.题目列表
1.找到小镇的法官
题目描述:
在一个小镇里,按从 1 到 N 标记了 N 个人。传言称,这些人中有一个是小镇上的秘密法官。
如果小镇的法官真的存在,那么:
小镇的法官不相信任何人。
每个人(除了小镇法官外)都信任小镇的法官。
只有一个人同时满足属性 1 和属性 2 。
给定数组 trust,该数组由信任对 trust[i] = [a, b] 组成,表示标记为 a 的人信任标记为 b 的人。
如果小镇存在秘密法官并且可以确定他的身份,请返回该法官的标记。否则,返回 -1。

示例:

输入:N = 2, trust = [[1,2]]
输出:2

题解:
设置一个list,如果 list[trust[i][0]]减一 [1]加一,若存在i list值为trust.length 则返回该i 否则不存在

2.不邻接植花
题目描述:
有 N 个花园,按从 1 到 N 标记。在每个花园中,你打算种下四种花之一。
paths[i] = [x, y] 描述了花园 x 到花园 y 的双向路径。
另外,没有花园有 3 条以上的路径可以进入或者离开。
你需要为每个花园选择一种花,使得通过路径相连的任何两个花园中的花的种类互不相同。
以数组形式返回选择的方案作为答案 answer,其中 answer[i] 为在第 (i+1) 个花园中种植的花的种类。花的种类用 1, 2, 3, 4 表示。保证存在答案。

示例:
输入:N = 3, paths = [[1,2],[2,3],[3,1]]
输出:[1,2,3]

题解:
首先生成一个邻接表,然后循环遍历从一号花园开始种花,color初始化为false,遍历与该花园相连的花园,存储他们的颜色,然后从不包含改颜色的数组中挑选出一个

3.冗余连接
题目描述:
在本问题中, 树指的是一个连通且无环的无向图。
输入一个图,该图由一个有着N个节点 (节点值不重复1, 2, …, N) 的树及一条附加的边构成。附加的边的两个顶点包含在1到N中间,这条附加的边不属于树中已存在的边。
结果图是一个以边组成的二维数组。每一个边的元素是一对[u, v] ,满足 u < v,表示连接顶点u 和v的无向图的边。
返回一条可以删去的边,使得结果图是一个有着N个节点的树。如果有多个答案,则返回二维数组中最后出现的边。答案边 [u, v] 应满足相同的格式 u < v。

示例:
输入: [[1,2], [1,3], [2,3]]
输出: [2,3]
解释: 给定的无向图为:
1
/
2 - 3

题解:
并查集思想,将所有顶点的父节点初始化为自己,对所有边进行遍历,找到一条边的两个顶点,如果两个顶点在同一个集合,返回该条边,如果不在,将这两个顶点加入同一个集合。

4.最小高度树
题目描述:
对于一个具有树特征的无向图,我们可选择任何一个节点作为根。图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树。给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们的根节点。
格式
该图包含 n 个节点,标记为 0 到 n - 1。给定数字 n 和一个无向边 edges 列表(每一个边都是一对标签)。
你可以假设没有重复的边会出现在 edges 中。由于所有的边都是无向边, [0, 1]和 [1, 0] 是相同的,因此不会同时出现在 edges 里。

示例:
输入: n = 4, edges = [[1, 0], [1, 2], [1, 3]]
0
|
1
/
2 3
输出: [1]

题解:
先定义一个邻接矩阵,将度为1的节点加入队列,把与这些节点相连的节点的度-1,如果为1,则加入队列。最后返回最小高度树

***5.网络延迟时间
题目描述:
有 N 个网络节点,标记为 1 到 N。
给定一个列表 times,表示信号经过有向边的传递时间。 times[i] = (u, v, w),其中 u 是源节点,v 是目标节点, w 是一个信号从源节点传递到目标节点的时间。
现在,我们从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1。

示例:
示例:

输入:times = [[2,1,1],[2,3,1],[3,4,1]], N = 4, K = 2
输出:2

题解:
迪杰斯特拉算法

6.判断二分图
题目描述:
给定一个无向图graph,当这个图为二分图时返回true。
如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这个图称为二分图。
graph将会以邻接表方式给出,graph[i]表示图中与节点i相连的所有节点。每个节点都是一个在0到graph.length-1之间的整数。这图中没有自环和平行边: graph[i] 中不存在i,并且graph[i]中没有重复的值。

示例:
输入: [[1,3], [0,2], [1,3], [0,2]]
输出: true
解释:
无向图如下:
0----1
| |
| |
3----2
我们可以将节点分成两组: {0, 2} 和 {1, 3}。

题解:
定义一个数值存储是否被访问,初始化为false,依次遍历,将一个顶点加入队列,visited=1,找出该顶点的相邻的顶点,如果visited=1,返回false,否则初始化为-1

7.所有可能的路径
题目描述:
给一个有 n 个结点的有向无环图,找到所有从 0 到 n-1 的路径并输出(不要求按顺序)
二维数组的第 i 个数组中的单元都表示有向图中 i 号结点所能到达的下一些结点(译者注:有向图是有方向的,即规定了 a→b 你就不能从 b→a )空就是没有下一个结点了。

示例:

输入:graph = [[1,2],[3],[3],[]]
输出:[[0,1,3],[0,2,3]]
解释:有两条路径 0 -> 1 -> 3 和 0 -> 2 -> 3

题解:
递归,如果node=n-1,则加入path,加入ans

8.地图分析
题目描述:
你现在手里有一份大小为 N x N 的 网格 grid,上面的每个 单元格 都用 0 和 1 标记好了。其中 0 代表海洋,1 代表陆地,请你找出一个海洋单元格,这个海洋单元格到离它最近的陆地单元格的距离是最大的。
我们这里说的距离是「曼哈顿距离」( Manhattan Distance):(x0, y0) 和 (x1, y1) 这两个单元格之间的距离是 |x0 - x1| + |y0 - y1| 。
如果网格上只有陆地或者海洋,请返回 -1。

示例:
示例 1:

输入:[[1,0,1],[0,0,0],[1,0,1]]
输出:2
解释:
海洋单元格 (1, 1) 和所有陆地单元格之间的距离都达到最大,最大距离为 2。

题解:
先将所有陆地入队,取出队列中的元素,将他们四周的海洋入队,并修改grid距离,返回最后一个grid

9.找到最终的安全状态
题目描述:
在有向图中, 我们从某个节点和每个转向处开始, 沿着图的有向边走。 如果我们到达的节点是终点 (即它没有连出的有向边), 我们停止。
现在, 如果我们最后能走到终点,那么我们的起始节点是最终安全的。 更具体地说, 存在一个自然数 K, 无论选择从哪里开始行走, 我们走了不到 K 步后必能停止在一个终点。
哪些节点最终是安全的? 结果返回一个有序的数组。
该有向图有 N 个节点,标签为 0, 1, …, N-1, 其中 N 是 graph 的节点数. 图以以下的形式给出: graph[i] 是节点 j 的一个列表,满足 (i, j) 是图的一条有向边。

示例:
输入:graph = [[1,2],[2,3],[5],[0],[5],[],[]]
输出:[2,4,5,6]
这里是上图的示意图。
Illustration of graph

题解:
寻找不在环中的节点并输出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值