Google interview question: disjoint-set questions

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)。

转载于:https://www.cnblogs.com/dshao/p/4615043.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值