求数组元素的全排列,数组不含重复元素

Permutations

Given a collection of numbers, return all possible permutations.

For example,
[1,2,3] have the following permutations:    
[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1].

求数组元素的全排列,数组不含重复元素

算法1:递归

类似于DFS的递归. 对于包含n个元素的数组,先确定第一位置的元素,第一个位置有n中可能(每次把后面的元素和第一个元素交换),然后求子数组[2…n]的全排列。由于一个数列的总共有n!个排列,因此时间复杂度为O(n!)

class Solution {
public:
    vector<vector<int> > permute(vector<int> &num) {
        vector<vector<int> > res;
        if(num.size() == 0)return res;
        vector<int> tmpres;
        permuteRecur(num, 0, res, tmpres);
        return res;
    }

    void permuteRecur(vector<int> &num, int index, vector<vector<int> >&res, vector<int>&tmpres)
    {
        if(index == num.size())
        {
            res.push_back(tmpres);
            return;
        }
        for(int i = index; i < num.size(); i++)
            {
                swap(num[index], num[i]);
                tmpres.push_back(num[index]);
                permuteRecur(num, index+1, res, tmpres);
                tmpres.pop_back();
                swap(num[index], num[i]);
            }
    }
};

Permutations II

Given a collection of numbers that might contain duplicates, return all possible unique permutations.

For example,
[1,1,2] have the following unique permutations:  
[1,1,2], [1,2,1], and [2,1,1].

求数组元素的全排列,数组含重复元素

分析:要避免重复,就要保证我们枚举某个位置的元素时,不能枚举重复。

算法2:

在算法1的基础上,当我们枚举第i个位置的元素时,若要把后面第j个元素和i交换,则先要保证[i…j-1]范围内没有和位置j相同的元素。有以下两种做法(1)可以每次在需要交换时进行顺序查找;(2)用哈希表来查重。具体见下面的代码。

注意不要误以为以下两种做法能够去重:(1)最开始先对数组进行排序,以后每次交换时,只要保证当前要交换的元素和前一个元素不同,这种做法是错误的,虽然开始进行了排序,但是元素的交换会使数组再次变的无序(2)每次进入递归函数permuteRecur时,对从当前索引开始的子数组排序,这种做法也是错误的,因为每次交换元素后,我们要恢复交换的元素,如果在递归函数内排序,就不能正确的恢复交换的元素。    

class Solution {
public:
    vector<vector<int> > permuteUnique(vector<int> &num) {
        vector<vector<int> > res;
        if(num.size() == 0)return res;
        vector<int> tmpres;
        permuteRecur(num, 0, res, tmpres);
        return res;
    }

    void permuteRecur(vector<int> &num, int index, vector<vector<int> >&res, vector<int>&tmpres)
    {
        if(index == num.size())
        {
            res.push_back(tmpres);
            return;
        }
        for(int i = index; i < num.size(); i++)
            if(i == index || !find(num, index, i, num[i]))
            {
                swap(num[index], num[i]);
                tmpres.push_back(num[index]);
                permuteRecur(num, index+1, res, tmpres);
                tmpres.pop_back();
                swap(num[index], num[i]);
            }
    }
    //从数组的[start,end)范围内寻找元素target
    bool find(vector<int> &num, int start, int end, int target)
    {
        for(int i = start; i < end; i++)
            if(num[i] == target)
                return true;
        return false;
    }
};
class Solution {
public:
    vector<vector<int> > permuteUnique(vector<int> &num) {
        vector<vector<int> > res;
        if(num.size() == 0)return res;
        vector<int> tmpres;
        permuteRecur(num, 0, res, tmpres);
        return res;
    }

    void permuteRecur(vector<int> &num, int index, vector<vector<int> >&res, vector<int>&tmpres)
    {
        if(index == num.size())
        {
            res.push_back(tmpres);
            return;
        }
        unordered_set<int> umap;
        for(int i = index; i < num.size(); i++)
            if(umap.find(num[i]) == umap.end())
            {
                umap.insert(num[i]);
                swap(num[index], num[i]);
                tmpres.push_back(num[index]);
                permuteRecur(num, index+1, res, tmpres);
                tmpres.pop_back();
                swap(num[index], num[i]);
            }
    }
};

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索数组
, vector
, return
, 第i个元素
, index
, 元素
, 查重软件
, num
, 查重
, 数据查重/去重
, 重复元素
, 数组全排列
, 重复数组元素
不重复排列
有重复元素的排列问题、带重复元素的排列、有重复元素的全排列、重复元素的排列问题、有重复元素的排列,以便于您获取更多的相关知识。

时间: 2024-12-31 09:55:01

求数组元素的全排列,数组不含重复元素的相关文章

java去除已排序数组中的重复元素_java

题目描述 给定一个已排序的数组,去除数组中的重复元素,只保留一个重复的元素,并且返回新的数组长度. 要求: 不要给数组分配额外的空间,你必须使用常量的内存大小进行原地操作. 例如: 给出数组A=[1,1,2],你的函数调用之后必须返回长度length=2,并且A现在变成[1,2]. 输入 一个已排序的数组,例如[1,1,2]. 输出 返回数组新的长度,例如length=2. 快慢指针法 设置fast指针遍历数组,slow指针指向不重复元素的下一位. public static int remov

百度面试题:求一个已排序的数组中绝对值最小的元素

题目为: 有一个已经排序的数组(升序),数组中可能有正数.负数或0,求数组中元素的绝对值最小的数,要求,不能用顺序比较的方法(复杂度需要小于O(n)),可以使用任何语言实现 例如,数组{-20,-13,-4, 6, 77,200} ,绝对值最小的是-4. 这一题该如何求呢? 初步的解决思路是:     1.数组中的元素全为正,取最左边的数字:     2.数组中的元素全为负,取最右边的数字的绝对值:     3.数组中有正数有负数,就用二分法查找,判断中间元素的符号        a)中间元素为

减治求有重复元素的全排列

求n个元素的全排列的所有解可以用减治法:每次拎出一个数做前缀,对剩下的元素再求全排列,直至只剩一个元素.代码源自<算法分析与设计(王晓东)>,复杂度O(n!) 1 //输出k~m的所有全排列 2 void perm(int k,int m) 3 { 4 if(k==m) 5 { 6 for(int i=0;i<=m;i++) 7 printf("%d ", list[i]); 8 printf("\n"); 9 }else 10 { 11 for(

vector定义-定义元素为int数组的vector时出错: vector&amp;amp;lt;int [10]&amp;amp;gt; vec;

问题描述 定义元素为int数组的vector时出错: vector<int [10]> vec; 为什么不能这样定义?请问错在哪里? 正常的定义方式是vector> vec; 但是vector为什么不能直接存放数组呢?非常疑惑,求大神解答- 解决方案 vector<int *> vector<vector<int>> 这两个试试看 解决方案二: 像老曹那样,定义指针 解决方案三: int数组不是模版类型. 你这个需要双层vector vector>

[经典面试题][淘宝]求首尾相连数组的最大子数组和

题目 给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首尾是相连的.数组中一个或多个连续元素可以组成一个子数组,其中存在这样的子数组arr[i],-arr[n-1],arr[0],-,arr[j],现在请你这个ACM_Lover用一个最高效的方法帮忙找出所有连续子数组和的最大值(如果数组中的元素全部为负数,则最大和为0,即一个也没有选). 输入: 输入包含多个测试用例,每个测试用例共有两行,第一行是一个整数n(1<=n<= 100000),表示数组的长度

c语言-关于去除数组中重复元素的问题

问题描述 关于去除数组中重复元素的问题 源代码:#include #include int main() { int *a; int n,i,j; scanf("%d",n); a=(int *)malloc(n*sizeof(int)); for (i=0;i<n;i++) scanf("%d",&a[i]); for (i=0;i<n;i++) for (j=1;j<n;j++) if (a[i]==a[j]) printf (&quo

数组唯一key-2个数组元素顺序不同,认为是同一个数组

问题描述 2个数组元素顺序不同,认为是同一个数组 有2个数组比如[1,2,3,4]和[4,3,2,1],仅仅排序不同,有什么快速的算法认为是同一个数组? 或者数组元素能算出key,而此key和元素顺序无关. 求Java实现 解决方案 对它排序,然后比较,或者对数组求和,得到hash,如果和相同虽然不一定数组相同,但是和不同,一定不同,所以可以进一步筛选. 解决方案二: 如果数组没有重复,放到set中,然后直接比较set,就OK了 解决方案三: 要判断两个数组相同,而且还要考虑的数组元素是无序,最

求算法,一个n长度的数组,要将数组分成n个组

问题描述 求算法,一个n长度的数组,要将数组分成n个组每个组将数组中的所有元素分成m份,且不能重复出现(m的值等于组号即第几组就是分几份,不考虑排序)如数组,List<int>arr=newList<int>{1,2,3};要分成3个组,第一个组和n个组是固定的第1个组将数组分成1份,即vargroup=newList<List<int>>{newList<int>{1,2,3}};第2个组把数组中所有元素分成2份,可能出现以下的分法:1.var

怎么调用数组中的元素全是数组

问题描述 求大神们帮我看看 解决方案 解决方案二:不就是个数组么?解决方案三:直接用下标访问就是了,你的问题是什么解决方案四:本身就是元素为数组的数组,当然里面全是数组啦!解决方案五:[0,0]13.0意思是在二维数组0,0位置的元素值为13.0解决方案六:这个数组是从MATLAB中的元胞数组调出来的,数组中的元素全部是数组,请问怎么取出其中的数组元素解决方案七:这个就是一个二维数组喽doubles=double[0][0];s=13.0解决方案八:inta=arr[0][0]这样解决方案九:差