1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| object SubsetsWithDup {
def main(args: Array[String]): Unit = { println(subsetsWithDup(Array(5, 4, 5, 4, 3, 3, 1, 1, 1, 2))) }
def subsetsWithDup(nums: Array[Int]): List[List[Int]] = { var numMap = Map[Int, Int]() nums.foreach(a => if (!numMap.contains(a)) numMap += (a -> 1) else numMap += (a -> (numMap.get(a).get + 1)))
val res = mutable.HashSet[List[Int]]() res += List() res += nums.toList for (i <- 1 until nums.length) { backtrack(numMap, mutable.Map(), new ListBuffer[Int](), res, i) } res.toList }
def backtrack(numMap: Map[Int, Int], selected: mutable.Map[Int, Int], selectList: ListBuffer[Int], res: mutable.HashSet[List[Int]], target: Int): Unit = { if (!selected.values.isEmpty && selected.values.reduce(_ + _) == target) { res += selectList.clone().sorted(Ordering.Int).toList return }
for (i <- numMap.keySet) { if (selected.get(i) == None || selected.get(i).get < numMap.get(i).get) { selected += (i -> (if (selected.get(i) == None) 1 else selected.get(i).get + 1)) selectList += (i) backtrack(numMap, selected, selectList, res, target) if (selected.get(i).get > 1) { selected += (i -> (selected.get(i).get - 1)) } else { selected -= i } selectList -= (i) } } }
}
|