代码题(19)— 组合与排列

Posted eilearn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代码题(19)— 组合与排列相关的知识,希望对你有一定的参考价值。

1、77. 组合

给定两个整数 n 和 k,返回 1 ... 中所有可能的 k 个数的组合。

示例:

输入: n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]
class Solution {
public:
    vector<vector<int>> combine(int n, int k) {
        vector<vector<int>> res;
        vector<int> temp;
        combSum(n, k, 1, temp, res);
        return res;
    }
    void combSum(int n, int k, int pos, vector<int> &temp, vector<vector<int>> &res)
    {
        if(temp.size() == k)
        {
            res.push_back(temp);
            return;
        }
        for(int i=pos;i<=n;++i)
        {
            temp.push_back(i);
            combSum(n,k,i+1,temp,res);
            temp.pop_back();
        }
    }
         
};

 2、46. 全排列

给定一个没有重复数字的序列,返回其所有可能的全排列。

示例:

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

(1)这道题是求全排列问题,给的输入数组没有重复项,这跟之前的组合和类似,解法基本相同,但是不同点在于那道不同的数字顺序只算一种,是一道典型的组合题,而此题是求全排列问题,还是用递归DFS来求解。这里我们需要用到一个visited数组来标记某个数字是否访问过,然后在DFS递归函数从的循环应从头开始,而不是从level开始,这是和组合不同的地方,其余思路大体相同。

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> res;
        vector<int> temp;
        vector<int> visited(nums.size(),0);
        permuteDfs(nums,0,visited,temp,res);
        return res;
        
    }
    void permuteDfs(vector<int> &nums, int pos, vector<int> &visited, vector<int> &temp, vector<vector<int>> &res)
    {
        if(pos == nums.size())
            res.push_back(temp);
        else
        {
            for(int i=0;i<nums.size();++i)
            {
                if(visited[i] == 0)
                {
                    visited[i] = 1;
                    temp.push_back(nums[i]);
                    permuteDfs(nums,pos+1,visited,temp,res);
                    temp.pop_back();
                    visited[i] = 0;
                }
            }
        }
        
    }
};

 

(2)还有一种递归的写法,更简单一些,这里是每次交换num里面的两个数字,经过递归可以生成所有的排列情况。

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> res;
        permuteDfs(nums, 0, res);
        return res;
        
    }
    void permuteDfs(vector<int> &nums, int pos, vector<vector<int>> &res)
    {
        if(pos == nums.size())
            res.push_back(nums);
        for(int i=pos;i<nums.size();++i)
        {
            swap(nums[pos], nums[i]);
            permuteDfs(nums, pos+1, res);
            swap(nums[pos], nums[i]);
        }
    }
    
};

 

以上是关于代码题(19)— 组合与排列的主要内容,如果未能解决你的问题,请参考以下文章

itertools 排列组合

《程序员面试金典(第6版)》面试题 08.08. 有重复字符串的排列组合(回溯算法,全排列问题)C++

面试题 08.08. 有重复字符串的排列组合

面试题 08.08. 有重复字符串的排列组合

Java 全排列与组合

Python算法题——国际象棋棋盘(排列组合问题,最小的K个数)