码迷,mamicode.com
首页 > 其他好文 > 详细

Google interview question: disjoint-set questions

时间:2015-07-02 06:36:01      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:

Question:

Given a n,m which means the row and column of the 2D matrix and an array of pair A( size k). Originally, the 2D matrix is all 0 which means there is only sea in the matrix. The list pair has k operator and each operator has two integer A[i].x, A[i].y means that you can change the grid matrix[A[i].x][A[i].y] from sea to island. Return how many island are there in the matrix after each operator.

Example

Given n = 3m = 3, array of pair A = [(0,0),(0,1),(2,2),(2,1)].

return [1,1,2,2].

Note

0 is represented as the sea, 1 is represented as the island. If two 1 is adjacent, we consider them in the same island. We only consider up/down/left/right adjacent.

原题链接:http://www.lintcode.com/en/problem/number-of-islands-ii/

这题可以用disjoint-set来实现。关于disjoint-set的基本概念,以下的这个视频讲解的十分清楚。视频链接:https://www.youtube.com/watch?v=ID00PMy0-vE

 

我们首先实现disjoint-set的数据结构。在disjoint-set中,每一个节点有3个属性,父亲节点、rank值(近似深度)和数据。定义Node如下:

class Node{
    int rank;
    int data;
    Node parant;
}

其次,disjoint-set有3个方法,makeSet(int data):创建一个单独的集合;findSet(int data):寻找该数据所在集合的代表节点(根节点);union(int data1, int data2):合并两个集合。另外,我们需要一个HashMap来储存数据和其对应节点的映射。

public class DisjointSet {
    private Map<Integer, Node> map = new HashMap<Integer, Node>();
    public boolean makeSet(int data){
        if(map.containsKey(data)) return false;
        else{
            Node node = new Node();
            node.rank = 0;
            node.data = data;
            node.parant = node;
            map.put(data, node);
            return true;
        }
    }
    public int findSet(int data){
        if(!map.containsKey(data)) return -1;
        return findSet(map.get(data)).data;
    }
    public Node findSet(Node node){
        Node parant = node.parant;
        if(parant == node) return node;
        node.parant = findSet(parant);
        return node.parant;
    }
    public void union(int data1, int data2){
        Node parant1 = findSet(map.get(data1));
        Node parant2 = findSet(map.get(data2));
        if(parant1 == parant2) return;
        if(parant1.rank>=parant2.rank){
            parant1.rank = parant1.rank==parant2.rank?parant1.rank+1:parant1.rank;
            parant2.parant = parant1;
        }
        else {
            parant1.parant = parant2;
        }
    }
}

假设m次操作,n个元素,其时间复杂度为O(m α(n)),其中α(n)是一个增长极慢的函数,在实际应用中小于4,因此时间复杂度约为O(m)。  最后,我们的问题就变得十分简单。对于每一次将海变成岛屿的操作,相当于一次makeSet的操作,然后对其四周进行findSet操作,如果其值不为-1,那么进行union操作。因此,对于每一次makeSet操作,最多需要4次union操作,时间复杂度为O(1),对于k次操作,时间复杂度为O(k)。

Google interview question: disjoint-set questions

标签:

原文地址:http://www.cnblogs.com/dshao/p/4615043.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!