leetcode刷题 log day 28

【感悟】写题越来越快啦,而且可以自己写出来了,每天努力一点点,真的可以慢慢变厉害!希望看到我的 blog 的有缘人也可以努力,真的没有想象中的难!

  • 93.复原IP地址
    思路】这道题的重点在于在哪加 . ,递归的起始位置要考虑清楚加了 . 之后的下标,终止条件是小于 255 和首位不能为 0 。判断结束是要遍历到最后并且 path 长度为 4 。(因为我的方法是最后添加进 res 时把 path 数组改成字符串并添加 .,所以不用考虑递归时开始的下标问题)

    var restoreIpAddresses = function(s) {
      let res = [], path = [];
      const isValid = (start, end) => {
        // 开头不能为 0
        if (start !== end && s[start] === '0') return false;
        // 不能大于 255
        if (s.slice(start, end + 1) > 255) return false;
        return true;
      }
      const backtracking = startIndex => {
        if (path.length === 4 && startIndex > s.length -1) {
          if (isValid(startIndex, s.length - 1)) {
            res.push(path.join('.'));
          }
        }
    
        for (let i = startIndex; i < s.length; i++) {
          if (!isValid(startIndex, i)) return;
          path.push(s.slice(startIndex, i + 1));
          backtracking(i + 1);
          path.pop();
        }
      }
      backtracking(0);
      return res;
    };
    
  • 78.子集
    思路】之前我们做的递归组合问题,抽象成一个 N 叉树,组合问题收集的是 N 叉树的所有子节点,那么求数组子集就是收集 N 叉树的所有节点res 收集结果就得在每次 path 数组完成一次收集之后,才能得到每个节点的值。

    var subsets = function(nums) {
      let path = [], res = [[]];
      const backtracking = startIndex => {
        if (startIndex === nums.length) return;
    
        for (let i = startIndex; i < nums.length; i++) {
          path.push(nums[i]);
          res.push([...path]);
          backtracking(i + 1);
          path.pop();
        }
      }
      backtracking(0);
      return res;
    };
    
  • 90.子集II
    思路】这道题比上一道题多了一个对于重复的判断。对于重复问题:老套路就是先对数组进行排序,再使用 used 数组记录已经使用过的元素,就可以解决重复问题。
    展示的两种其实并没有什么区别,只是写的时候发现有 bug,修改时,发现 res push 值的位置不一样,那么对于终止条件的判断也不一样,其实也就是改 bug 的两种方式罢了,但自己写错了,就记录一下子~

    var subsetsWithDup = function(nums) {
      let res = [], path = [],
          used = new Array(nums.length).fill(0);
          sortNums = nums.sort((a, b) => a - b);
      const backtracking = (startIndex, used) => {
        if (startIndex > sortNums.length) return;
          res.push([...path]);
    
        for (let i = startIndex; i < sortNums.length; i++) {
          if (sortNums[i] === sortNums[i -1] && used[i - 1] === 0) continue;
          path.push(sortNums[i]);
          used[i] = 1;
          backtracking(i + 1, used);
          path.pop();
          used[i] = 0;
        }
      }
      backtracking(0, used);
      return res;
    };
    
    var subsetsWithDup = function(nums) {
      let res = [[]], path = [],
          used = new Array(nums.length).fill(0),
          sortNums = nums.sort((a, b) => a - b);
      const backtracking = (startIndex, used) => {
        if (startIndex >= sortNums.length) return;  // 如果这里是大于的话,那么 res 初始值就等于 [],因为当等于 sortNums.length 的时候会 push 一次空(例如上一个方法)
    
        for (let i = startIndex; i < sortNums.length; i++) {
          if (sortNums[i] === sortNums[i -1] && used[i - 1] === 0) continue;
          path.push(sortNums[i]);
          res.push([...path]);
          used[i] = 1;
          backtracking(i + 1, used);
          path.pop();
          used[i] = 0;
        }
      }
      backtracking(0, used);
      return res;
    };
    

参考代码随想录:https://www.programmercarl.com/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值