图的表示

图的比较方便的表示方法有两种,第一种是matrix(比如有number of island这种),第二种是邻接矩阵的形式。

如果题目中给了边的信息,最好转化成邻接矩阵。


DFS

    void dfs(graph, visited, current){
        if (visited[current]) return;
        visited[current] = true; // Need to set this line first
        for (auto neighbor:graph[current]){
            if(!visited[neighbor]) {
                dfs(graph,visited, neighbor);
            }
        }
    }

BFS


并查集

在判断联通情况的时候可以和dfs/bfs互换,union find优点是可以方便处理动态图,缺点是并不是O(1)time,而bfs/dfs相反。

在面试的时候可以写两个并查集版本,一个是简易版本,一个是完整带weighted quick-union and path compression的版本。

class UF { // 完整版本
	// union-find, bfs
	int N;
	int[] id;
	int[] sz;
	int segments;
	public UF(int n){
		N = n;
		segments = n;
		id = new int[N];
	    sz = new int[N];
		for(int i=0; i<N; i++){
			id[i] = i;
			sz[i] = 1;
		}
	}	
	public int root(int i) {
		while(i!=id[i]){
			id[i] = id[id[i]]; // path compression
			i = id[i];
		}
		return i;
	}
	public void connect(int p, int q){
		int i = root(p);
		int j = root(q);
		if(i == j) return;
		if(sz[i]<sz[j]) { // if-else: weighted quick-union
			id[i] = j;
			sz[j] += sz[i];
		}
		else if(sz[i]>sz[j]) {
			id[j] = i;
			sz[i] += sz[j];
		}
		else {
			id[j] = i;
			sz[i] += sz[j];
		}
		segments--;
	}
	public boolean connected(int p, int q) {
		if(root(p)==root(q)){
			return true;
		}
		return false;
	}
}

简单版本 (LC261代码)

public class Solution {
    public boolean validTree(int n, int[][] edges) {
        // initialize n isolated islands
        int[] nums = new int[n];
        Arrays.fill(nums, -1);
        
        // perform union find
        for (int i = 0; i < edges.length; i++) {
            int x = find(nums, edges[i][0]);
            int y = find(nums, edges[i][1]);
            
            // if two vertices happen to be in the same set
            // then there's a cycle
            if (x == y) return false;
            
            // union
            nums[x] = y;
        }
        
        return edges.length == n - 1;
    }
    
    int find(int nums[], int i) {
        if (nums[i] == -1) return i;
        return find(nums, nums[i]);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值