Go Tour Exercise: Equivalent Binary Trees

前端 未结 23 1637
攒了一身酷
攒了一身酷 2020-12-12 23:39

I am trying to solve equivalent binary trees exercise on go tour. Here is what I did;

package main

import \"tour/tree\"
import \"fmt\"

// Walk walks the tr         


        
相关标签:
23条回答
  • 2020-12-13 00:14

    because the question just said the tree just 10 nodes,then following is my answer after read other answers:

    func Walk(t *tree.Tree, ch chan int) {
        defer close(ch)
    
        var walker func(t *tree.Tree)
        walker = func(t *tree.Tree) {
            if t == nil {
                return
            }
    
            walker(t.Left)
            ch <- t.Value
            walker(t.Right)
        }
        walker(t)
    }
    
    func Same(t1, t2 *tree.Tree) bool {
        ch1, ch2 := make(chan int), make(chan int)
        go Walk(t1, ch1)
        go Walk(t2, ch2)
    
        for range make([]struct{}, 10) {
            if <-ch1 != <-ch2 {
                return false
            }
        }
        return true
    }
    
    0 讨论(0)
  • 2020-12-13 00:16

    You got it almost right, there's no need to use the select statement because you will go through the default case too often, here's my solution that works without needing to count the number of nodes in the tress:

    func Same(t1, t2 *tree.Tree) bool {
        ch1, ch2 := make(chan int), make(chan int)
        go Walk(t1, ch1)
        go Walk(t2, ch2)
        for i := range ch1 {
            j, more := <-ch2
            if more {
                if i != j { return false }
            } else { return false }
        }
    
        return true
    }
    
    0 讨论(0)
  • 2020-12-13 00:16

    Here's a solution that doesn't depend on differing tree lengths, neither does it depend on traversal order:

    package main
    
    import (
        "fmt"
        "golang.org/x/tour/tree"
    )
    
    // Walk walks the tree t sending all values
    // from the tree to the channel ch.
    func Walk(t *tree.Tree, ch chan int) {
        var walk func(*tree.Tree)
        walk = func(tr *tree.Tree) {
            if tr == nil {
                return
            }
    
            walk(tr.Left)
            ch <- tr.Value
            walk(tr.Right)
        }
    
        walk(t)
        close(ch)
    }
    
    func merge(ch chan int, m map[int]int) {
        for i := range ch {
            count, ok := m[i]
            if ok {
                m[i] = count + 1
            } else {
                m[i] = 1
            }
        }
    }
    
    // Same determines whether the trees
    // t1 and t2 contain the same values.
    func Same(t1, t2 *tree.Tree) bool {
        ch1 := make(chan int, 100)
        ch2 := make(chan int, 100)
        m := make(map[int]int)
    
        go Walk(t1, ch1)
        go Walk(t2, ch2)
    
        merge(ch1, m)
        merge(ch2, m)
    
        for _, count := range m {
            if count != 2 {
                return false
            }
        }
    
        return true
    }
    
    0 讨论(0)
  • 2020-12-13 00:18

    Here's the solution I came up with :

    func Walker(t *tree.Tree, ch chan int){
        if t==nil {return}
        Walker(t.Left,ch)
        ch<-t.Value
        Walker(t.Right,ch)   
    }
    
    func Walk(t *tree.Tree, ch chan int){
       Walker(t,ch)
       close(ch)
    }
    
    func Same(t1, t2 *tree.Tree) bool{
        ch:=make(chan int)
        dh:=make(chan int)
        go Walk(t1,ch)
        go Walk(t2,dh)
    
        for i:=range ch {
            j,ok:=<-dh
            if(i!=j||!ok)  {return false} 
        }
    
        return true
    }
    
    0 讨论(0)
  • 2020-12-13 00:18

    I wrote 2 versions that always read both channels to the end:

    package main
    
    import (
        "fmt"
        "golang.org/x/tour/tree"
    )
    
    func Walk(t *tree.Tree, ch chan int) {
        var walker func(t *tree.Tree)
        walker = func(t *tree.Tree) {
            if t == nil {
                return
            }
            walker(t.Left)
            ch <- t.Value
            walker(t.Right)
        }
        walker(t)
        close(ch)
    }
    
    func Same(t1, t2 *tree.Tree, sameChan func(ch1, ch2 chan int) bool) bool {
        ch1, ch2 := make(chan int), make(chan int)
        go Walk(t1, ch1)
        go Walk(t2, ch2)
    
        return sameChan(ch1, ch2)
    }
    
    func sameChan1(ch1, ch2 chan int) bool {
        areSame := true
        for {
            v1, ok1 := <-ch1
            v2, ok2 := <-ch2
    
            if !ok1 && !ok2 {
                return areSame
            }
    
            if !ok1 || !ok2 || v1 != v2 {
                areSame = false
            }
        }
    }
    
    func sameChan2(ch1, ch2 chan int) bool {
        areSame := true
        for v1 := range ch1 {
            v2, ok2 := <-ch2
    
            if !ok2 || v1 != v2 {
                areSame = false
            }
        }
        for _ = range ch2 {
            areSame = false
        }
        return areSame
    }
    
    func main() {
        fmt.Println(Same(tree.New(1), tree.New(1), sameChan1))
        fmt.Println(Same(tree.New(2), tree.New(1), sameChan1))
        fmt.Println(Same(tree.New(1), tree.New(2), sameChan1))
    
        fmt.Println(Same(tree.New(1), tree.New(1), sameChan2))
        fmt.Println(Same(tree.New(2), tree.New(1), sameChan2))
        fmt.Println(Same(tree.New(1), tree.New(2), sameChan2))
    }
    
    0 讨论(0)
  • 2020-12-13 00:19
    package main
    
    import (
        "fmt"
        "golang.org/x/tour/tree"
    )
    
    // Walk walks the tree t sending all values
    // from the tree to the channel ch.
    func Walk(t *tree.Tree, ch chan int) {
        walkRecursive(t, ch)
        close(ch)
    }
    
    func walkRecursive(t *tree.Tree, ch chan int) {
        if t == nil {
            return
        }
        walkRecursive(t.Left, ch)
        ch <- t.Value
        walkRecursive(t.Right, ch)
    }
    
    // Same determines whether the trees
    // t1 and t2 contain the same values.
    func Same(t1, t2 *tree.Tree) bool {
        ch1 := make(chan int)
        ch2 := make(chan int)
        go Walk(t1, ch1)
        go Walk(t2, ch2)
    
        for {
            v1, ok1 := <-ch1
            v2, ok2 := <-ch2
            if ok1 != ok2 {
                return false
            }
            if !ok1 {
                return true
            }
            if v1 != v2 {
                return false
            }
        }
    }
    
    func main() {
        fmt.Println(Same(tree.New(1), tree.New(2)))
    }
    
    
    0 讨论(0)
提交回复
热议问题