LeetCode-May-Week4 Daily Challenge: Possible Bipartition

本文探讨了在图论中实现二分匹配的两种方法:一种是基于自定义映射的迭代策略,该策略通过分配节点到不同组来判断图是否可以被二分;另一种是深度优先搜索(DFS)方法,通过构建图并进行深度遍历来解决二分匹配问题。文章详细解释了每种方法的实现细节,并对比了它们的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值