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)
}
}
}
}