1. 程式人生 > >DFS-求全排列

DFS-求全排列

以[1,2,3]為例,若第一個元素為1,則還要求[2,3]的全排列;第一個元素為2,則還有求[1,3]的全排列........故可用遞迴實現深度優先遍歷,遍歷出所有的可能

vector<vector<int>> permute(vector<int> &nums) {
        // write your code here
        vector<vector<int>> res;
        vector<int> P;//P[i]表示第i個位置填的元素
        vector<bool> visited(nums.size(),false);//保證同一個數不會被選多次
        DFS(res,P,visited,nums,0);
        return res;
    }
    void DFS(vector<vector<int>>& res,vector<int>& P,vector<bool>& visited,vector<int>& nums,int index){
        if(index==nums.size()){//下標從0-n-1,index==n時則表示都完成了
            res.push_back(P);
            return;
        }
        //執行到這裡,表示還沒填完
        for(int i=0;i<nums.size();++i){
            if(!visited[i]){//第i個位置的數還沒有用
                P.push_back(nums[i]);
                visited[i]=true;
                DFS(res,P,visited,nums,index+1);//填下一個位置
                //恢復
                visited[i]=false;
                P.pop_back();
            }
        }
    }


第一次接觸的話,可以藉助畫圖的方法理解,index表示正在填的位置的下標,需要藉助一個數組visited表示是否使用過了


由圖中可以看出程式的流程:

1.由於迴圈一直是i=0,i<nums.size(),實際上每個節點下面都有3個節點,只是有的重複了,故用斜線劃掉,為了簡單,圖中只畫了一部分。這也正是visited陣列的作用,避免了重複

2.程式剛進入時,i=0.index=0,第一個位置填了1,然後DFS進入index=1的那一層搜尋,i=0,但是nums[0]已經用過了,故i++,i=1開始,第二個位置填了2..........以此類推,搜到最深處則存入res中,這正是深度優先遍歷。可以看出程式是按圖中從上到下,從左到右的順序進行搜尋,搜尋出所有的情況