LeetCode-May-Week4 Daily Challenge: Possible Bipartition

32 篇文章 3 订阅

5/27 daily challenge: Possible Bipartition

 

My own solution, a bit faster than DFS(depth-first search):

func possibleBipartition(n int, dislikes [][]int) bool {
	// key = ppl(1..n), val = group(0 or 1)
	group := make(map[int]int)
	ngroup := 0
	for len(dislikes) > 0 {
		skipped := make([][]int, 0)
		for i := 0; i < len(dislikes); i++ {
			a, b := dislikes[i][0], dislikes[i][1]
			va, ea := group[a]
			vb, eb := group[b]
			switch {
			case !ea && !eb:
				if len(group) - ngroup == 0 {
                    // assign group to node a/b to trigger the loop
					group[a] = 0
					group[b] = 1
				} else {
                    // if neither a nor b has been assigned a group, delay to next loop
					skipped = append(skipped, dislikes[i])
				}
			case ea && !eb:
				group[b] = 1 - va
			case !ea && eb:
				group[a] = 1 - vb
			case ea && eb:
				if va == vb {
					return false
				}
			}
			//fmt.Printf("len(group)=%v, group=%v\n", len(group), group)
			//fmt.Printf("skipped=%v\n", skipped)
		}

		ngroup = len(group)
		dislikes = skipped
	}

	return true
}

The DFS version:

func possibleBipartition(n int, dislikes [][]int) bool {
	graph := make(map[int][]int)
	for i := 0; i < len(dislikes); i++ {
		a, b := dislikes[i][0], dislikes[i][1]
		_, ea := graph[a]
		_, eb := graph[b]
		if !ea {
			graph[a] = make([]int, 0)
		}
		if !eb {
			graph[b] = make([]int, 0)
		}
		graph[a] = append(graph[a], b)
		graph[b] = append(graph[b], a)
	}

	group := make([]int, n)
	for i := 0; i < n; i++ {
		group[i] = -1
	}

	for i := 1; i <= n; i++ {
		if group[i-1] < 0 && !dfs(i, 0, graph, group) {
			return false
		}
	}

	return true
}

func dfs(i int, v int, graph map[int][]int, group []int) bool {
	if group[i-1] < 0 {
		group[i-1] = v
	} else {
		if group[i-1] !=  v {
			return false
		} else {
			return true
		}
	}

	_, exist := graph[i]
	if exist {
		for _, j := range graph[i] {
			//fmt.Printf("graph[%v]=%v\n", i, graph[i])
			if !dfs(j, 1-v, graph, group) {
				return false
			}
		}
	}

	return true
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值