【问题标题】:Guide to improve/optimize my terrible code for is graph bipartite in scala改进/优化我糟糕代码的指南是 scala 中的图二分法
【发布时间】:2021-02-25 19:26:45
【问题描述】:

我为https://leetcode.com/problems/is-graph-bipartite/ 编写了这段代码 它有效,但我认为代码很糟糕。问题:

  1. 发现isBipartite=false时怎么破
  2. 我如何仅对未访问的 g.keys 进行 dfs(查找图是否为二分图)。 (当有 2 个图没有相互连接时)
import scala.collection.immutable.Queue
case class Step(q: Queue[Int]=Queue(),visited: List[Int]=List(),colors: List[Int]=List(),isBipartite: Boolean = true)
object Solution {
    def isBipartite(graph: Array[Array[Int]]): Boolean = {
        val g= graph.foldLeft(Map[Int,List[Int]]())((mp,arr)=>{
            val i= graph.indexOf(arr)
             if(arr.isEmpty){
                 mp + (i->List())
}else
            arr.foldLeft(mp)((m,v)=>{
                m + (i->(m.getOrElse(i,Nil) :+ v))
            })
        })
        //println(g)
        val colors = List.fill(graph.size)(-1)
        //println(colors)
        g.keys.foldLeft(Step())((s,k)=>{
                if(!s.visited.contains(k) || s.isBipartite==true)
                bfs(k,g,s.copy(q=Queue(k),visited=(s.visited:+ k),colors=colors.updated(k,1)))
            else
                s.copy(isBipartite=false)
        
        }).isBipartite
    }
    
    
    def bfs(start: Int, g: Map[Int,List[Int]], step1: Step): Step = {
        
    val s=Stream.iterate(step1) {
      case (step) =>
        
        //dequeue
        val (vertex, rest)=step.q.dequeue
        val newS=g.getOrElse(vertex,Nil).foldLeft(step)((s,v)=>{
            //println("vertex color for vertex "+vertex+" "+s.colors(vertex))
             //println("v color "+s.colors(v))
            if(s.colors(vertex)==s.colors(v)){
                //println("is not bipartite")
                 step.copy(isBipartite=false)
            }else if(s.colors(v) == -1){
                 //println(s.colors)
                 s.copy(colors=s.colors.updated(v,(1-s.colors(vertex))))    
            }else{
                 s
            }                                       
        })
        //add neighbours to queue
       val newQueue=rest.enqueue(g.getOrElse(vertex,Nil).filterNot(newS.visited.contains))    
        //mark neighbours visited
       val newVisited: List[Int] = newS.visited ++ g.getOrElse(vertex,Nil)
            
        newS.copy(q=newQueue,visited=newVisited)
    }.takeWhile(t=> t.q.nonEmpty).filterNot(n=>n.isBipartite).headOption
       if(!s.isEmpty)
            s.get
        else
            Step()
   
  }
    
}

【问题讨论】:

    标签: algorithm scala data-structures functional-programming


    【解决方案1】:

    我想出了一个更好的解决方案

    import scala.collection.immutable.Queue
    case class Step(q: Queue[Int]=Queue(),colors: List[Int]=List(),isBipartite: Boolean = true)
    object Solution {
        def isBipartite(graph: Array[Array[Int]]): Boolean = {
            //create a g
            val g= graph.foldLeft(Map[Int,List[Int]]())((mp,arr)=>{
                val i= graph.indexOf(arr)
                 if(arr.isEmpty) mp + (i->List())
                else arr.foldLeft(mp)((m,v)=>m + (i->(m.getOrElse(i,Nil) :+ v)))
            })
            
            //init colors array
            val colors = List.fill(graph.size)(-1)
            
            //iterate over all g keys which are not processed
            g.keys.foldLeft(Step(Queue(),colors,true))((s,k)=>
                    if(s.colors(k) == -1 || s.isBipartite==true){
                        bfs(k,g,s.copy(q=Queue(k),colors=s.colors.updated(k,1)))
                    } else s
            ).isBipartite
        }
        
        //color of neighbors should be opposite of vertex to be bipartite
        def bfs(start: Int, g: Map[Int,List[Int]], step: Step): Step = {
            Stream.iterate(step) {
                case (step) =>
                val (vertex, rest)=step.q.dequeue
                g.getOrElse(vertex,Nil).foldLeft(step.copy(q=rest))((s,v)=>{
                if(!s.isBipartite)  s
                else if(s.colors(vertex)==s.colors(v)) s.copy(isBipartite=false)            
    else if(s.colors(v) == -1) s.copy(q=s.q.enqueue(v),colors=s.colors.updated(v,(1-s.colors(vertex))))    
                else s                                      
            })  
        }.takeWhile(t=> t.q.nonEmpty).last
      }
        
    }
    

    【讨论】:

    • 查看CodeReview@SE。我最讨厌的一个问题:“一切”(公开可见)是什么,整个代码的用途是什么?
    猜你喜欢
    • 2013-11-12
    • 2010-09-08
    • 1970-01-01
    • 2015-11-23
    • 2011-05-04
    • 1970-01-01
    • 2011-08-02
    • 2014-09-07
    • 1970-01-01
    相关资源
    最近更新 更多