leetcode permutation

本文介绍了利用回溯法进行数据交换与nextpermutation算法来实现数据排列优化的详细步骤与原理。通过递归交换与深度优先搜索,解决了数据排列问题,并针对具有重复元素的情况提供了优化策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 利用回溯法进行数据交换。第一次交换时将第零位分别与 第0,1,..n-1位交换。第二次交换时将第1位与第1,2...n-1位交换。注意由于是递归地进行交换,故实际的交换顺序是按深度优先搜索来的。

class Solution {
public:
    vector<vector<int> > permute(vector<int> &num) {
        int len =num.size();
        vector<vector<int>> v;
        if(len==0)return v;
        subpermute(0,len,num,v);
        return v;
    }
    void subpermute(int level,int len,vector<int>&num,vector<vector<int>> &v){
        if(level==len-1){
            v.push_back(num);
        }
        for(int i=level;i<len;i++){
            int tmp=num[i];
            num[i]=num[level];
            num[level]=tmp;
            //swap(num[i],num[level]);
            subpermute(level+1,len,num,v);
            num[level]=num[i];
            num[i]=tmp;
            
          //  swap(num[i],num[level]);
        }
    }
};



2.next permutation算法:

观察数字 41352:它的下一个是41523 怎么得到的呢?我们从后往前进行扫描,扫描到第一个a[k-1]<a[k]的数字,我们可以知道交换这一位我们可以得到下一个更大的数,已知当 i>k时,a[i]>a[i+1],是递减序列,因此k之后的数很有可能会比a[k]小,我们必须从k位往后扫描,找到最小的j,与之交换,然后再将j之后的数据逆序排放,(因为原来是按从大到小排的)

class Solution {
public:
	void nextpermute(vector<int> &in){
		int size=in.size();
		int k;
		int i=size-1;
		while(i>0&&in[i-1]>in[i]){
			i--;
		}
		
		
		int j=i;
		while(j<size&&in[j]>in[i-1]){
			j++;
		}
				cout<<i<<" "<<j<<endl;
		//all the num was rank  descending 
		if(i==0){
			reverse(in.begin(),in.end());
		}

		else{
			swap(in[i-1],in[j-1]);
			reverse(in.begin()+i,in.end());
		}
	}
    vector<vector<int> > permute(vector<int> &num) {
        int len =num.size();
        vector<vector<int> > res;
       
        if(len==0)return res;
        res.push_back(num);
        if(len==1)return res;
        
        int total=1;
        for(int i=len;i>0;i--){total*=i;}
        for(int i=1;i<total;i++){
        	nextpermute(num);
        	res.push_back(num);
        	for(int j=0;j<num.size();j++){
        		cout<<num[j];
        	}
        	cout<<endl;
        	
        }
        
        
        return res;
    }
};


leetcode permutationII

当元素有重复时 ,我们仍然可以利用上述方法得到nextpermutation ,只是在从后往前找的时候在相等的时候可以一直往前找。当新生成的序列等于原来的序列的时候 程序停止。当采用交换的方法去进行解题时 注意为了避免重复数据进行交换的问题。

应当进行判断 对于每个level: 对level和i之间的数据进行遍历,如果a[j]==a[i]则不能做交换,若a[i]==a[level]也不作交换。

class Solution {
public:
    vector<vector<int> > permuteUnique(vector<int> &num) {
       
        int len =num.size();
        vector<vector<int> > v;
        if(len==0)return v;
        subpermute(0,len,num,v);
        return v;
    }
        bool inline hassample(vector<int>&num,int i,int level){
        //cout<<i<<" "<<level<<endl;
        if(i==level)return false;
        if(num[level]==num[i])return true;
        //return false;
        int j=level;
        
        while(j<i){
        	if(num[j]==num[i]){
        		return true;
        	}
        	j++;
        }
        return false;
         
    }
    void subpermute(int level,int len,vector<int>&num,vector<vector<int> > &v){
        if(level==len-1){
            v.push_back(num);
            for(int i=0;i<num.size();i++){
            	cout<<num[i];
            }
            cout<<endl;
        }
        for(int i=level;i<len;i++){
            if(hassample(num,i,level))continue;
            int tmp=num[i];
            num[i]=num[level];
            num[level]=tmp;
            //swap(num[i],num[level]);
            subpermute(level+1,len,num,v);
            num[level]=num[i];
            num[i]=tmp;
            
          //  swap(num[i],num[level]);
        }
    }    
    
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值