zoukankan      html  css  js  c++  java
  • 46. Permutations

    问题:

    给定一个数组,求对该数组进行全排列的所有结果。

    Example 1:
    Input: nums = [1,2,3]
    Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
    
    Example 2:
    Input: nums = [0,1]
    Output: [[0,1],[1,0]]
    
    Example 3:
    Input: nums = [1]
    Output: [[1]]
     
    Constraints:
    1 <= nums.length <= 6
    -10 <= nums[i] <= 10
    All the integers of nums are unique.
    

      

    解法:Backtracking(回溯算法)DFS(深度优先搜索 Depth-First-Search)

    回溯算法框架:

     1 result = []
     2 def backtrack(路径, 选择列表):
     3     if 满足结束条件:
     4         result.add(路径)
     5         return
     6 
     7     for 选择 in 选择列表:
     8         做选择
     9         backtrack(路径, 选择列表)
    10         撤销选择

    对于本问题,两个变量:

    • 路径:已经选择好的前几位结果
    • 选择列表:对每个位置上元素的选择可能性

    处理过程:

    • base:递归退出条件:选择到最后一位结束,这里为已经选择好路径长度==给出的数组长度。
    • 做选择:对于当前位置,选择其中一个可用数字a。
      • 路径.add(a)
      • 选择列表.delete(a)
    • 撤销选择:回退到选择数字a之前的状况。
      • 路径.delete(a)
      • 选择列表.add(a)

    代码参考:

     1 class Solution {
     2 public:
     3     void traverse(vector<int> path, vector<int> nums) {
     4         if(nums.empty()) {
     5             result.push_back(path);
     6             return;
     7         }
     8         for(int i=0; i<nums.size(); i++) {
     9             vector<int> numstmp(nums);
    10             path.push_back(nums[i]);
    11             numstmp.erase(numstmp.begin()+i);
    12             traverse(path, numstmp);
    13             path.pop_back();
    14         }
    15         return;
    16     }
    17     vector<vector<int>> permute(vector<int>& nums) {
    18         vector<int> path;
    19         traverse(path, nums);
    20         return result;
    21     }
    22 private:
    23     vector<vector<int>> result;
    24 };

    改进:

    每次新建numstmp,太耗费内存,

    -> 在做选择的时候,path中如果已经存在【选择列表】中的元素。说明该元素已被占用,则continue,不进行尝试。

    要判断是否存在,vector中没有很好的方法,因此,引入unordered_set 等同path所存储内容。

    使用count方法进行判断是否存在。

    代码参考:

     1 class Solution {
     2 public:
     3     void traverse(vector<int> path, vector<int> nums, unordered_set<int> pathset) {
     4         if(path.size()==nums.size()) {
     5             result.push_back(path);
     6             return;
     7         }
     8         for(int i=0; i<nums.size(); i++) {
     9             if(pathset.count(nums[i])!=0) continue;
    10             path.push_back(nums[i]);
    11             pathset.insert(nums[i]);
    12             traverse(path, nums, pathset);
    13             path.pop_back();
    14             pathset.erase(nums[i]);
    15         }
    16         return;
    17     }
    18     vector<vector<int>> permute(vector<int>& nums) {
    19         vector<int> path;
    20         unordered_set<int> pathset;
    21         traverse(path, nums, pathset);
    22         return result;
    23     }
    24 private:
    25     vector<vector<int>> result;
    26 };

    改进:swap方法

     对给定数组,进行元素交换,所得数组即为一个解。

     1 class Solution {
     2 public:
     3     void traverse(vector<int> nums, int pos) {
     4         if(pos==nums.size()) {
     5             result.push_back(nums);
     6             return;
     7         }
     8         for(int i=pos; i<nums.size(); i++) {
     9             swap(nums[i], nums[pos]);
    10             traverse(nums, pos+1);
    11             swap(nums[i], nums[pos]);
    12         }
    13         return;
    14     }
    15     vector<vector<int>> permute(vector<int>& nums) {
    16         traverse(nums, 0);
    17         return result;
    18     }
    19 private:
    20     vector<vector<int>> result;
    21 };
  • 相关阅读:
    linux-centos7 安装 maven 代码管理工具,以及常见配置
    linux-centos7 安装 jre + tomcat 实现 web 服务器
    python 开发语言 博客目录
    生存分布函数
    债务偿还
    密度聚类算法
    POI兴趣点搜索
    区域地址搜索
    地址之间的距离
    地理坐标转换
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14206207.html
Copyright © 2011-2022 走看看