zoukankan      html  css  js  c++  java
  • 【算法总结】排列组合的序列产生问题

    1. Next Permutation

      首先,从最尾端开始往前寻找两个相邻元素,令第一元素为 *i,第二元素为 *ii,且满足 *i < *ii;找到这样一组相邻元素后,再从尾端开始往前检验,找出第一个大于 *i 的元素,令为 *j,将 i,j 元素对调,再将 ii 之后的所有元素颠倒排列。

     1 void nextPermutation(vector<int>& nums) {
     2         if(nums.empty())
     3             return;
     4         int n = nums.size();
     5         for (int i = n - 2; i >=0; --i) {
     6             if (nums[i] >= nums[i + 1])
     7                 continue;
     8             int j = n - 1;
     9             while (j >= 0 && nums[j] <= nums[i]) --j;
    10             swap(nums[i], nums[j]);
    11             reverse(nums.begin() + i + 1, nums.end());
    12             return;
    13         }
    14         // 进行至最前面,重排
    15         reverse(nums.begin(), nums.end());
    16     }

    2.Prev Permutation

      首先,从最尾端开始往前寻找两个相邻元素,令第一元素为 *i,第二元素为 *ii,且满足 *i  > *ii;找到这样一组相邻元素后,再从尾端开始往前检验,找出第一个小于*i 的元素,令为 *j,将 i,j 元素对调,再将 ii 之后的所有元素颠倒排列。

     1 void prevPermutation(vector<int>& nums) {
     2         if(nums.empty())
     3             return;
     4         int n = nums.size();
     5         for (int i = n - 2; i >=0; --i) {
     6             if (nums[i] <= nums[i + 1])
     7                 continue;
     8             int j = n - 1;
     9             while (j >= 0 && nums[j] >= nums[i]) --j;
    10             swap(nums[i], nums[j]);
    11             reverse(nums.begin() + i + 1, nums.end());
    12             return;
    13         }
    14         reverse(nums.begin(), nums.end());
    15     }

    3. Permutations(全排列)

       (1)回溯法

     1 vector<vector<int>> permute(vector<int>& nums) {
     2         vector<vector<int>> res;
     3         vector<int> cur;
     4         vector<bool> visited(nums.size(), false);
     5         
     6         dfs(nums, res, cur, visited);
     7         
     8         return res;
     9     }
    10     
    11     void dfs(const vector<int>& nums, vector<vector<int>>& res, vector<int>& cur, vector<bool>& visited) {
    12         if (cur.size() == nums.size()) {
    13             res.push_back(cur);
    14             return;
    15         }
    16         
    17         for (int i = 0; i < nums.size(); ++i) {
    18             if (visited[i] == false) {
    19                 cur.push_back(nums[i]);
    20                 visited[i] = true;
    21                 dfs(nums, res, cur, visited);
    22                 cur.pop_back();
    23                 visited[i] = false;
    24             }
    25         }
    26     }

      (2)递归 1:

     1 vector<vector<int>> permute(vector<int>& nums) {
     2         vector<vector<int>> res;
     3         
     4         recursive(nums, res, 0);
     5         
     6         return res;
     7     }
     8     
     9     void recursive(vector<int>& nums, vector<vector<int>>& res, int start) {
    10         if (start >= nums.size()) {
    11             res.push_back(nums);
    12         }
    13         for (int i = start; i < nums.size(); ++i) {
    14             swap(nums[start], nums[i]);
    15             recursive(nums, res, start + 1);
    16             swap(nums[start], nums[i]);
    17         }
    18     }

        递归2:

    当n=1时,数组中只有一个数a1,其全排列只有一种,即为a1

    当n=2时,数组中此时有a1a2,其全排列有两种,a1a2和a2a1,那么此时我们考虑和上面那种情况的关系,我们发现,其实就是在a1的前后两个位置分别加入了a2

    当n=3时,数组中有a1a2a3,此时全排列有六种,分别为a1a2a3, a1a3a2, a2a1a3, a2a3a1, a3a1a2, 和 a3a2a1。那么根据上面的结论,实际上是在a1a2和a2a1的基础上在不同的位置上加入a3而得到的。

      (3)借用next_permutation的函数

     4. The Kth Permutation Sequence

      The set [1,2,3,…,n] contains a total of n! unique permutations. Given n and k, return the kth permutation sequence.

     1 string getPermutation(int n, int k) {
     2         string res;
     3         string dict = "123456789";
     4         int factorial = 1;
     5         for (int i = 1; i < n; ++i) {
     6             factorial *= i;
     7         }
     8         --k;
     9         while (n--) {
    10             int pos = k / factorial;
    11             res += dict[pos];
    12             k %= factorial;
    13             factorial /= (n ? n : 1);
    14             dict.erase(pos, 1);
    15         }
    16         return res;
    17     }
  • 相关阅读:
    oracle 常用SQL
    ActiveMQ持久化方式
    集中队列的模式
    EDA: Event-Driven Architecture事件驱动架构
    ActiveMQ消息队列介绍
    Nginx 用log_format设置日志格式
    log4j的ConversionPattern参数的格式含义
    真正的轻量级WebService框架——使用JAX-WS(JWS)发布WebService
    Java的注解机制——Spring自动装配的实现原理
    java interface 默认值
  • 原文地址:https://www.cnblogs.com/Atanisi/p/8649164.html
Copyright © 2011-2022 走看看