goroutine+channel+dfs+双指针整活,思路参看官方4

111 阅读1分钟

653. 两数之和 IV - 输入二叉搜索树 - 力扣(Leetcode) leetcode官方4的解法核心就是直接在BST上操作双指针,但是又因为不好同时控制两个递归的进度,就采取了迭代的方式。

我就想,同时两个指针一个从前往后递归,一个从后往前递归,这不开两个goroutine就好了?最多再来一个goroutine做中间人控制。channel来做数据和信号的通信。 1685092098227.png

于是有了以下代码,就是三个goroutine,反复用到了阻塞控制流程。 ps.效率肯定不行滴,你就当是复习channel的使用吧,咱初级go程序员也很少有场景能用到goroutine呀,珍惜罢(悲。

func findTarget(root *TreeNode, target int) bool {
	over := make(chan bool)
	sigCh1 := make(chan struct{})
	sigCh2 := make(chan struct{})
	dataCh1 := make(chan int)
	dataCh2 := make(chan int)
	go func() {
		var scan func(node *TreeNode)
		scan = func(node *TreeNode) {
			if node == nil {
				return
			}
			scan(node.Left)
			<-sigCh1
			dataCh1 <- node.Val
			scan(node.Right)
		}
		scan(root)
	}()
	go func() {
		var scan func(node *TreeNode)
		scan = func(node *TreeNode) {
			if node == nil {
				return
			}
			scan(node.Right)
			<-sigCh2
			dataCh2 <- node.Val
			scan(node.Left)
		}
		scan(root)
	}()
	go func() {
		var l, r int
		sigCh1 <- struct{}{}
		l = <-dataCh1
		sigCh2 <- struct{}{}
		r = <-dataCh2
		for {
			switch {
			case l == r:
				over <- false
				return
			case l+r == target:
				over <- true
				return
			case l+r < target:
				sigCh1 <- struct{}{}
				l = <-dataCh1
			case l+r > target:
				sigCh2 <- struct{}{}
				r = <-dataCh2
			}
		}
	}()
	return <-over
}