• ⑮ 算法设计思想之“回溯算法”


    一、理论

    1. 简介

    • 回溯算法是 算法设计 中的一种方法
    • 回溯算法是一种 渐进式 寻找并构建问题解决方法的策略
    • 回溯算法会先从一个可能的动作开始解决问题,如果不行就回溯并选择另一个动作,直到将问题解决

    2. 什么问题适合用回溯算法解决?

    • 有很多路
    • 这些路里,有 死路, 也有 出路
    • 通常需要递归来模拟所有路

    3. 全排列

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

    • 用递归模拟出所有情况
    • 遇到包含重复元素的情况,就回溯
    • 收集所有到达递归终点的情况,并返回

    二、刷题

    1. 全排列(46)

    1.1 题目描述

    • 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案

    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、没有重复情况
    • 有出路、有死路
    • 考虑使用回溯算法

    1.3 解题步骤

    • 用递归模拟出所有情况
    • 遇到包含重复元素的情况,就回溯
    • 收集所有到达递归终点的情况,并返回
    function permute(nums) {
      const res = [];
      const backtrack = path => {
        if(path.length === nums.length) {
          res.push(path)
        }
        nums.forEach(n => {
          if(path.includes(n)) { return; }
          backtrack(path.concat(n))
        })
      };
      backtrack([]);
      return res;
    }
    

    1.4 时间复杂度&空间复杂度

    • 时间复杂度:O(n!)
    • 空间复杂度:O(n)

    2. 子集(78)

    2.1 题目描述

    • 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)
    • 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集

    2.2 解题思路

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

    • 要求:1、所有子集;2、没有重复元素
    • 有出路,有死路

    2.3 解题步骤

    • 用递归模拟出所有情况
    • 保证接的数字都是后面的数字
    • 收集所有到达递归终点的情况,并返回
    function subsets(nums) {
      const res = [];
      const backtrack = (path, l, start) => {
        if(path.length === l) {
          res.push(path);
          return;
        }
        for(let i = start; i < nums.length; i++) {
          backtrack(path.concat(nums[i]), l, i+1)
        }
      };
      for(let i = 0; i <= nums.length; i++) {
        backtrack([], i, 0)
      }
      return res;
    }
    

    2.4 时间复杂度&空间复杂度

    • 时间复杂度:O(2^n)
    • 空间复杂度:O(n)

    三、总计 -- 技术要点

    • 回溯算法是 算法设计 中的一种方法
    • 回溯算法是一种 渐进式 寻找并构建问题解决方法的策略
    • 回溯算法会先从一个可能的动作开始解决问题,如果不行就回溯并选择另一个动作,直到将问题解决

    什么问题适合用回溯算法?

    • 有很多路
    • 这些路里,有 死路, 也有 出路
    • 通常需要递归来模拟所有路

    适合回溯算法解决的问题

    • 全排列
    • 子集
  • 相关阅读:
    常用的dos命令
    java环境的配置
    javascript面向对象个人理解
    js如何获取样式?
    springboot新建项目遇到Whitelabel Error Page
    CSS 隐藏页面元素的 几 种方法总结
    优美动听的葫芦丝名曲
    大前端资料合集
    CSS实现背景透明,文字不透明(兼容所有浏览器)
    文字上下无缝滚动效果
  • 原文地址:https://www.cnblogs.com/pleaseAnswer/p/15879728.html
Copyright © 2020-2023  润新知