leetcode Redundant Connection

Redundant Connection

题目详情:

In this problem, a tree is an undirected graph that is connected and has no cycles.

The given input is a graph that started as a tree with N nodes (with distinct values 1, 2, ..., N), with one additional edge added. The added edge has two different vertices chosen from 1 to N, and was not an edge that already existed.

The resulting graph is given as a 2D-array of edges. Each element of edges is a pair [u, v] with u < v, that represents anundirected edge connecting nodes u and v.

Return an edge that can be removed so that the resulting graph is a tree of N nodes. If there are multiple answers, return the answer that occurs last in the given 2D-array. The answer edge [u, v] should be in the same format, with u < v.

Example 1:

Input: [[1,2], [1,3], [2,3]]
Output: [2,3]
Explanation: The given undirected graph will be like this:
  1
 / \
2 - 3

Example 2:

Input: [[1,2], [2,3], [3,4], [1,4], [1,5]]
Output: [1,4]
Explanation: The given undirected graph will be like this:
5 - 1 - 2
    |   |
    4 - 3

Note:

The size of the input 2D-array will be between 3 and 1000. Every integer represented in the 2D-array will be between 1 and N, where N is the size of the input array.

解题方法:

解题方法1:使用并查集。首先看到题目给出边的大小在3到1000,可知顶点的大小最大为2000, 所以我们开辟一个大小为2000的数组存每个节点的parent,可以初始化每个节点的parent为它本身,但是为了方便,我选择初始化每个节点的parent为-1。每当从edges中取出一条边,则判断他们是否有同一个parent,如果是的话,则说明这条边是多余的一条边,返回这条边。如果不是的话,则将边的左方的parent,指向右方的parent(或者将边的右方的parent,指向左方的parent)。
能够这样做的原因是题目说明了只删除一条边则可以变成无环图。

解题方法2:使用dfs递归搜索,判断是否存在环。用邻接链表 map<int, set<int> > graph,存储图的信息。首先每从edges中取出一条边,判断这条边的左边到右边是否存在环,如果存在,则返回这条边。如果不存在,则将无向图的边保存到graph中。
dfs判断顶点a,b是否存在环的方法。如果能在顶点a直接相连的顶点中找到b,则说明肯定存在环。如果顶点a直接相连的顶点中找不到b,则看从能否在与a相连的顶点到b是否存在环,如果存在环,也说明a到b存在环。这里要注意因为这是无向图,所以a直接相连的顶点有b,那么b直接相连的顶点也有a,为了避免在递归时出现a->b, b->a的情况,要维护一个变量pre,记录上次便利的顶点,可以初始化为-1。

代码详情:

class Solution {
public:
// 方法一
    /*vector<int> findRedundantConnection(vector<vector<int>>& edges) {
        vector<int> arr(2000, -1);
        for (int i = 0; i < edges.size(); i++) {
            int x = find(arr, edges[i][0]);
            int y = find(arr, edges[i][1]);
            if (x == y) return edges[i];
            arr[y] = x;
        }
        return {};
    }
    int find(vector<int>& arr, int tar) {
        while (arr[tar] != -1) {
            tar = arr[tar];
        }
        return tar;
    }*/

// 方法儿
    vector<int> findRedundantConnection(vector<vector<int>>& edges) {
        // makegarph
        map<int, set<int> > graph;
        for (int i = 0; i < edges.size(); i++) {
            if (dfs_hascycle(graph, edges[i][0], edges[i][1], -1)) return edges[i];
            graph[edges[i][0]].insert(edges[i][1]);
            graph[edges[i][1]].insert(edges[i][0]);
        }
        return {};
    }
    bool dfs_hascycle(map<int, set<int> >& graph, int a, int b, int pre) {
        if (graph[a].count(b)) return true;
        set<int>::iterator iter;
        for (iter = graph[a].begin(); iter != graph[a].end(); ++iter) {
            if (*iter == pre) {continue;}
            if (dfs_hascycle(graph, *iter, b, a)) {return true;}
        }
        return false;
    }
};


猜你喜欢

转载自blog.csdn.net/weixin_40085482/article/details/78787969