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

    一、题目说明

    题目是46. Permutations,给一组各不相同的数,求其所有的排列组合。难度是Medium

    二、我的解答

    这个题目,前面遇到过类似的。回溯法(树的深度优先算法),或者根据如下求解:

    刷题31. Next Permutation

    我考虑可以用dp做,写了一个上午,理论我就不说了,自己看代码:

    #include<iostream>
    #include<vector>
    #include<unordered_map>
    
    using namespace std;
    class Solution{
    	public:
    		vector<vector<int>> permute(vector<int>& nums) {
    			vector<vector<int>> res;
    			vector<vector<int>> next;
    		
    			unordered_map<int,vector<vector<int>>> dp;
    			vector<int> cur;
    			
    			if(nums.empty()) return res;
    			
    			cur.push_back(nums[0]);
    			res.push_back(cur);
    			dp[1] = res;
    			int currLength = 2;
    			for(int j=1;j<nums.size();j++){
    				res = dp[j];
    				next.clear();
    				
    				for(int k=0;k<currLength;k++){
    					cur.clear();
    				    cur.resize(j+1);
    					
    					for(int m=0;m<res.size();m++){
    						cur[k] = nums[j];
    						int t1=0,t2=0;
    						while(t2<res[m].size()){
    							if(cur[t1]!=nums[j]){
    								cur[t1] = res[m][t2];
    							}else{
    								++t1;
    								cur[t1] = res[m][t2];
    							}
    							t1++;
    							t2++;						
    						}
        				
    	    				next.push_back(cur);
    
    	    				cur.clear();
    	    				cur.resize(j+1);
    					}
    				}										
    						
    				currLength++;
    				dp[j+1] = next;
    			}
    			return dp[nums.size()];
    	    }
    };
    int main(){
    	Solution s;
    	vector<int> nums = {1,2,3,4};
    	vector<vector<int>> r = s.permute(nums);
    	for(int i=0;i<r.size();i++){
    		for(int j=0;j<r[i].size();j++){
    			cout<<r[i][j]<<" ";
    		}
    		cout<<"
    ";
    	}
        
        
    	return 0;
    }
    

    性能如下:

    Runtime: 8 ms, faster than 98.85% of C++ online submissions for Permutations.
    Memory Usage: 9.5 MB, less than 46.27% of C++ online submissions for Permutations.
    

    三、优化措施

    dp算法,是按照空间换时间的,所以时间还可以,空间就差了点。

    下面是回溯算法的代码,可读性好多了:

    class Solution{
    	private:
    		vector<vector<int>> result;
    		vector<int> path;
    		vector<bool> used;
    	public:
    		//枚举每个位置放哪个数 
    		void dfs(const vector<int>&nums,int pos){
    			if(pos == nums.size()){
    				result.push_back(path);
    				return;
    			}
    			for(int i=0;i<nums.size();i++){
    				if(!used[i]){
    					path.push_back(nums[i]);
    					used[i] = true;
    					dfs(nums,pos+1);
    					used[i] = false;
    					path.pop_back();
    				}
    			}
    		}
    		vector<vector<int>> permute(vector<int>& nums) {
    	        if(nums.empty()){
    	        	return result;
    			}
    
                used.resize(nums.size());
    			dfs(nums,0);
    			return result;
    	    }
    };
    
    所有文章,坚持原创。如有转载,敬请标注出处。
  • 相关阅读:
    [Leetcode]7. 整数反转
    [Leetcode]6. Z 字形变换
    [Leetcode]5. 最长回文子串
    java实现各种排序算法1
    [Leetcode]4. 寻找两个正序数组的中位数
    css设置字体单行,多行超出省略号显示
    如何获得select被选中option的value和text和......
    在vue项目中,将juery设置为全局变量
    js中遍历对象的属性和值的方法
    深入理解JS的事件绑定、事件流模型
  • 原文地址:https://www.cnblogs.com/siweihz/p/12245079.html
Copyright © 2011-2022 走看看