leetcode-46-全排列

題目描述:

給定一個沒有重複數字的序列,返回其全部可能的全排列。函數

示例:ui

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

 

要完成的函數:

vector<vector<int>> permute(vector<int>& nums) spa

 

說明:

一、給定一個一維的vector,裏面裝着彼此不重複的int型整數,要求輸出全部這些整數有可能組成的全排列。指針

每一個全排列存儲在一維的vector中,全部的全排列存儲在二維的vector中,最後返回二維的vector。code

 

二、這道題又是熟悉的樹開枝散葉類的題目,這種題咱們都是用遞歸作的。blog

在樹的每一個節點上,規律是一致的,用遞歸是最方便的作法。遞歸

舉個例子,好比[1,2,3,4],咱們在第一個節點上,有4種選擇,1/2/3/4,io

若是選擇了2,那麼第二個節點上,有3種選擇,1/3/4,class

若是選擇了4,那麼第三個節點上,有2種選擇,1/3。gui

但存在一個問題,咱們怎麼知道當前節點上的全部選擇?咱們要建一個「彈藥庫」嗎,每次迭代一個進入循環?

但其實全排列就是元素之間的不斷交換,咱們能夠利用這一點,下降時間複雜度。

代碼以下:(附詳解)

 void digui(vector<int>& nums,vector<vector<int>>& res,int left,int right,int* t) { if(left==right)//退出條件 { res[*t]=nums; (*t)++; return; } for(int i=left;i<=right;i++)//當i==left時,其實沒有交換,直接進入遞歸,當i!=left時,發生交換,進入遞歸 { swap(nums[i],nums[left]); digui(nums,res,left+1,right,t); swap(nums[i],nums[left]); } } vector<vector<int>> permute(vector<int>& nums) { int s1=nums.size(),result=s1,left=0,right=s1-1,count=0;//count表示當前是第幾個全排列 int *t=&count;//定義一個指針,指向count,便於後續處理 for(int i=s1-1;i>1;i--)//result表示一共有多少個全排列 result*=i; vector<vector<int>>res(result,nums);//提早申請好空間,避免屢次申請空間形成的時間浪費 digui(nums,res,left,right,t);//直接進入遞歸 return res;//最終返回二維的vector } 

還不是很清楚的同窗,能夠手推一下全過程,邏輯會清晰不少。

這道題咱們不用自建「彈藥庫」,交換一下nums中的元素,nums就是咱們的彈藥庫。

上述代碼實測8ms,beats 100.00% of cpp submissions。

相關文章
相關標籤/搜索