代码随想录第25天 | * 491.递增子序列 * 46.全排列 * 47.全排列 II

491.递增子序列

自己的做法:

      /**
       * @param {number[]} nums
       * @return {number[][]}
       */
      let road = [];
      let path = [];
      var findSubsequences = function (nums) {
        road = []; //road会有之前的数据,所以需要每次清空road
        brektraning(nums, 0);
        let obj = {};
        road.forEach((val) => {
          // 此处不能用 obj.name = '属性值'的方式 因为此处的val是变量,不是固定值
          obj[val] = val;
        });
        result = [];
        for (let key in obj) {
          result.push(key.split(",").map(Number));
        }
        return result;
      };

      const brektraning = function (nums, er) {
        for (let i = er; i < nums.length; i++) {
          path.push(nums[i]);
          min = nums[i];
          brektraning(nums, i + 1);
          if (path.length >= 2 && grt(path)) road.push([...path]); //push不能为数组,所以只能先展开
          path.pop();
          while (nums[i + 1] && nums[i] === nums[i + 1]) i++; //去重
        }
      };
      let grt = function (s) {
        for (let i = 0; i < s.length - 1; i++) {
          if (s[i] > s[i + 1]) return false;
        }
        return true;
      };


第一想法

子集的方法,在返回结果时判断是否相同和是否大于,但内存和时间都很复杂。
不判断的话,会出现 [1,2,3,4,5,6,7,8,9,10,1,1,1,1,1] 这样的出错


困难

  • 二维数组的去重

Set去重是比较数组中存入的值,当数组内值为简单数据类型,存入的就是值本身。比较的就是值本身。而二维数组存入的值为地址值,即使存入的相同,地址值也会不同。所以无法使用Set来进行去重。

  • while (nums[i + 1] && nums[i] === nums[i + 1]) i++; 用这个去重是否有效?

无效!因为之前的 子集的题目都是从大到小的排列好了的,这道题明显不是


卡哥的做法:

var findSubsequences = function(nums) {
    let result = []
    let path = []
    function backtracing(startIndex) {
        if(path.length > 1) {
            result.push(path.slice())
        }
        let uset = []
        for(let i = startIndex; i < nums.length; i++) {
            if((path.length > 0 && nums[i] < path[path.length - 1]) || uset[nums[i] + 100]) {
                continue
            }
            uset[nums[i] + 100] = true
            path.push(nums[i])
            backtracing(i + 1)
            path.pop()
        }
    }
    backtracing(0)
    return result
};

思路打开!

代码随想录第25天 | * 491.递增子序列 * 46.全排列 * 47.全排列 II_第1张图片

  • 同一父节点下的同层上使用过的元素就不能再使用了

uset[nums[i] + 100] 用哈希


6.全排列

 /**
       * @param {number[]} nums
       * @return {number[][]}
       */

      var permute = function (nums) {
        let count = nums.length;
        let result = [];
        let path = [];
        let uset = new Array(count);
        uset.fill(0);
        backtracing(nums, uset);
        return result;

        function backtracing(nums, uset) {
          if (path.length === nums.length) {
            result.push(path.slice());
          }
          for (let i = 0; i < nums.length; i++) {
            if (uset[i]) {
              continue;
            }
            path.push(nums[i]);
            uset[i] = 1;
            backtracing(nums, uset);
            path.pop();
            uset[i] = 0;
          }
        }
      };

第一想法

因为数组里的数不重复,想的是哈希,如果是用过的,哈希为1。
但这个哈希竖着来,横着要清空,所以在pop()后要复原。
但是搞的时候没弄出来

backtracing在外面的时候,result为0,不知道为什么


思路

代码随想录第25天 | * 491.递增子序列 * 46.全排列 * 47.全排列 II_第2张图片


47.全排列 II

法一:

  /**
       * @param {number[]} nums
       * @return {number[][]}
       */
      var permuteUnique = function (nums) {
        let count = nums.length;
        let result = [];
        let path = [];
        let uset = new Array(count);
        uset.fill(0);
        backtracing(nums, uset);
        let obj = {};
        result.forEach((val) => {
          // 此处不能用 obj.name = '属性值'的方式 因为此处的val是变量,不是固定值
          obj[val] = val;
        });
        road = [];
        for (let key in obj) {
          road.push(key.split(",").map(Number));
        }
        return road;

        function backtracing(nums, uset) {
          if (path.length === nums.length) {
            result.push(path.slice());
          }
          for (let i = 0; i < nums.length; i++) {
            if (uset[i]) {
              continue;
            }
            path.push(nums[i]);
            uset[i] = 1;
            backtracing(nums, uset);
            path.pop();
            uset[i] = 0;
          }
        }
      };

法二:

  /**
       * @param {number[]} nums
       * @return {number[][]}
       */
      var permuteUnique = function (nums) {
        let count = nums.length;
        nums.sort((a,b)=>a-b)
        let result = [];
        let path = [];
        let uset = new Array(count);
        uset.fill(0);
        backtracing(nums, uset);
        return result;

        function backtracing(nums, uset) {
          if (path.length === nums.length) {
            result.push(path.slice());
          }
          for (let i = 0; i < nums.length; i++) {
            if (uset[i]) {
              continue;
            }
            path.push(nums[i]);
            uset[i] = 1;
            backtracing(nums, uset);
            path.pop();
            uset[i] = 0;
            while (nums[i + 1]!==undefined && nums[i] === nums[i + 1]) i++; //去重
          }
        }
      };

第一想法

法一:嘿嘿,上一题的结果拿来去重。

法二:sort然后在上一题的基础上面去重
代码随想录第25天 | * 491.递增子序列 * 46.全排列 * 47.全排列 II_第3张图片


困难

  • [0,1,0,0,9]过不了

while (nums[i + 1] && nums[i] === nums[i + 1]) i++; //去重
有问题,要写成nums[i + 1]!==undefined

你可能感兴趣的:(代码随想录,算法,javascript,leetcode)