leetcode刷题笔记四十七 全排列II

leetcode刷题笔记四十七 全排列II

源地址:47. 全排列 II

问题描述:

给定一个可包含重复数字的序列,返回所有不重复的全排列。

示例:

输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]

代码补充:

//本题基于46题的DFS与回溯方法,由于存在重复数字,需要对一些情况进行剪枝
//常用的重复数字剪枝手段为 先对于原始数组进行排序,而后进行判断
//如i>0时,nums(i-1) == nums(i)即出现重复数字,这是需要判断这种情况是否已经实现
//若used(i) == false,即靠前的重复数字已经进行回溯,当前重复数字排列已经出现进行剪枝
//本题使用了scala中的Breaks,scala本身并没有break和continue,需要借助util.control.Breaks包,使用breakable{}将跳出代码范围圈定
//需要注意的是ListBuffer的使用,ListBuffer可以做到头部插入,尾部插入,但是删除只能做到头部删除
import scala.collection.mutable
import util.control.Breaks._
object Solution {
    var path = mutable.ListBuffer[Int]()
    def permuteUnique(nums: Array[Int]): List[List[Int]] = {
      val sortedNum = nums.sorted
      val length = nums.length
      if (length == 0) return List()

      var res = mutable.ListBuffer[List[Int]]()
      //var path = mutable.ListBuffer[Int]()
      var used = mutable.ListBuffer.fill(length)(false)


      dfs(sortedNum, length, 0,  used, res)
      return res.toList
    }

    def dfs(nums:Array[Int], length:Int, depth:Int, used:mutable.ListBuffer[Boolean], res:mutable.ListBuffer[List[Int]]) : Unit = {
      if (depth == length) {
        res += (path.toList)
        return
      }


      for(i <- nums.indices){
        breakable{
          if(used(i) == true) break()
          if(i > 0 && nums(i-1) == nums(i) && used(i-1) == false) break()
          path += nums(i)
          used(i) = true
          dfs(nums, length, depth+1, used, res)
          used(i) = false
          path = path.dropRight(1)
        }
      }
    }
}
posted @ 2020-07-03 23:26  ganshuoos  阅读(111)  评论(0编辑  收藏  举报