刷题打卡:数组操作の全排列 II

75 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

一、题目描述:

全排列 II

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

示例 1:

输入:nums = [1,1,2]
输出:
[[1,1,2],
 [1,2,1],
 [2,1,1]]
 
示例 2:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

二、思路与实现:

思路一:

与上一篇不一样的是,本篇全排列带重复数字。但仍然适用回溯法;

  1. 基本回溯思路;
  2. 每次向某一路径后面添加新元素的时候,用一个set记录已加入的元素列表,如果判断之前已经加入过,则跳过当前元素。

代码实现:


var permuteUnique = function (nums) {
    nums.sort((a, b) => {
        return a - b
    })
    let result = []
    let path = []

    function backtracing( used) {
        if (path.length === nums.length) {
            result.push(path.slice())
            return
        }
        for (let i = 0; i < nums.length; i++) {
            if (i > 0 && nums[i] === nums[i - 1] && !used[i - 1]) {
                continue
            }
            if (!used[i]) {
                used[i] = true
                path.push(nums[i])
                backtracing(used)
                path.pop()
                used[i] = false
            }
        }
    }
    backtracing([])
    return result
};

思路二:

循环的时候,加一个对象缓存一下,下次再遇到这个数,开头的结果就直接略过了;

var permuteUnique = function (nums) {
    if (nums.length === 1) {
      return [nums];
    }
    let res = [], map = {};
    nums.forEach((e, index) => {
      if (!map[e]) {
        map[e] = 1;
        let arr = [...nums];
        arr.splice(index, 1);
        permuteUnique(arr).forEach((e1) => {
          let arr = [e, ...e1];
          res.push(arr);
        });
      }
    });
    return res;
};

三、总结:

这道题目和前一篇的区别在与:给定一个可包含重复数字的序列,要返回:所有不重复的全排列。

即:去重。抓住此点就行啦~~