LeetCode-310. Minimum Height Trees (JAVA) 图中最矮的树

310. Minimum Height Trees

For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.

Format
The graph contains n nodes which are labeled from 0 to n - 1. You will be given the number n and a list of undirected edges (each edge is a pair of labels).

You can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.

Example 1:

Given n = 4, edges = [[1, 0], [1, 2], [1, 3]]

        0
        |
        1
       / \
      2   3

return [1]

Example 2:

Given n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]

     0  1  2
      \ | /
        3
        |
        4
        |
        5

return [3, 4]

Note:

(1) 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.”

(2) The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.

 build graph first, then find leaf and remove them among their neighbors, level by level. Until left less 2 nodes

超时版本:

采用广度优先遍历,记录层数

public List<Integer> findMinHeightTrees(int n, int[][] edges) {
		List<Integer> list = new ArrayList<>();
		if (n == 1){
			list.add(0);
			return list;
		}// 初始化图
		Map<Integer, List<Integer>> map = new HashMap<>();
		for (int i = 0; i < edges.length; i++) {
			int first = edges[i][0];
			int second = edges[i][1];
			if (!map.containsKey(first))
				map.put(first, new ArrayList<>());
			map.get(first).add(second);
			if (!map.containsKey(second))
				map.put(second, new ArrayList<>());
			map.get(second).add(first);
		}
		Map<Integer, Integer> levelMap = new HashMap<>();
		for (int i = 0; i < n; i++) {
			Queue<Integer> q = new LinkedList<>();
			q.offer(i);
			int cur = 1;
			int next = 0;
			levelMap.put(i, 0);
			boolean vis[] = new boolean[n];
			while (!q.isEmpty()) {
				Integer val = q.poll();
				vis[val] = true;
				cur--;
				List<Integer> tmp = map.get(val);
				for (int j = 0; j < tmp.size(); j++) {
					if (!vis[tmp.get(j)]) {
						q.offer(tmp.get(j));
						next++;
					}
				}
				if (cur == 0) {
					cur = next;
					levelMap.put(i, levelMap.get(i) + 1);
					next = 0;
				}
			}
		}

		if (!levelMap.isEmpty()) {
			int min = 0;
			for (Entry<Integer, Integer> e : levelMap.entrySet()) {
				if (min == 0)
					min = e.getValue();
				else
					min = Math.min(min, e.getValue());
			}
			for (Entry<Integer, Integer> e : levelMap.entrySet()) {
				if (e.getValue() == min)
					list.add(e.getKey());
			}
		}
		return list;
	}

	public List<Integer> findMinHeightTrees(int n, int[][] edges) {
		// 始终指向度数一样的所有结点,
		List<Integer> leafs = new ArrayList<>();
		if (n <= 1) {
			leafs.add(0);
			return leafs;
		}
		// 初始化无向图
		Map<Integer, List<Integer>> graph = new HashMap<>();
		for (int i = 0; i < n; i++)
			graph.put(i, new ArrayList<>());
		int[] degree = new int[n];
		for (int[] edge : edges) {
			degree[edge[0]]++;
			degree[edge[1]]++;
			graph.get(edge[0]).add(edge[1]);
			graph.get(edge[1]).add(edge[0]);
		}
		for (int i = 0; i < n; i++)
			// 每个结点度最少为1,为0 的时候已经加入判断
			if (degree[i] == 1)
				leafs.add(i);
		while (n > 2) {

			List<Integer> newLeaf = new ArrayList<>();
			for (int leaf : leafs) {
				n--;
				// 类似拓扑排序
				// 遍历所有leaf的邻接点,并让度数减去1
				// 删除结点(让度数减去1)
				for (int nb : graph.get(leaf)) {
					if (--degree[nb] == 1)
						newLeaf.add(nb);
				}
			}
			leafs = newLeaf;

	
		}
		return leafs;
	}
207. Course Schedule

210. Course Schedule II




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值