1. 程式人生 > >通過【lintCode-15全排列問題】學習DFS演算法

通過【lintCode-15全排列問題】學習DFS演算法

這周發現畢業一年後自己對於技術的激情好像變得已經沒有以前那麼熱愛與執著了,不再像以前那樣每天想著都在學習新的技術,也不再因為每天沒有學習到新的東西而會感到負罪感。也或許是我在大公司裡由於長期沒有壓力的工作讓我習慣了這樣的日子,日復一日的輕鬆慣了導致的,但偶爾理智的我知道這種輕鬆的日子並不是我所想要的,至少現階段不是。幹IT這行還是不能墮落原地踏步,得向前看不能掉隊,應緊緊跟上科技的浪潮。

————————————————————————————————————————————————————

————————————————————————分隔線—————————————————————————

————————————————————————————————————————————————————

描述

給定一個數字列表,返回其所有可能的排列。

做這個問題如果一時沒想到解法,可以先參考一段比這個問題簡單的將0-N之前的所有排列全列出來的DFS演算法

import java.util.Scanner;

public class dfs {
    public static int[] arr = new int[1000];
    public static int[] flag = new int[1000];//標誌哪些數字已經被用

    public static void dfs(int order, int d) {
        if (order == d + 1) {
            for (int i = 1; i <= d; i++)
                System.out.print(arr[i]);
            System.out.println();
            return;
        }
        for (int i = 1; i <= d; i++) {
            if (flag[i] == 0)//如果該數字未被佔用
            {
                arr[order] = i;
                flag[i] = 1;//將該數字的訪問許可權置為1
                dfs(order + 1, d);
                flag[i] = 0;//重新將該數字的訪問許可權置為0
            }
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.print("請輸入一個全排列數:");
        while (in.hasNextInt()) {
            int ans = in.nextInt();//接收輸入的數字
            System.out.println(ans + "的所有全排列如下:");
            dfs(1, ans);
        }
    }

}

其執行結果如下圖:

有了上面的可參考程式碼後,再加以思考,可以發現上面程式碼的遞迴過程類似於建立了一顆可回溯的樹,通過遍歷每一個節點來找到符合條件的所有節點序列。

然後依葫蘆畫瓢,再將此問題的程式碼寫出來:

程式碼如下:

import java.util.ArrayList;
import java.util.List;

public class MyDfs {
    public static void main(String[] args) {
        MyDfs myDfs = new MyDfs();
        myDfs.permute(new int[]{1, 2, 3});
    }

    public List<List<Integer>> permute(int[] nums) {
        boolean[] hasAccessFlagArray = new boolean[nums.length];
        int[] tempArray = new int[nums.length];
        List<List<Integer>> resultList = new ArrayList<>();
        dfsFunc(0, tempArray, nums, hasAccessFlagArray, resultList);
        for (List<Integer> integers : resultList) {
            for (Integer integer : integers) {
                System.out.print(integer + " ");
            }
            System.out.println();
        }
        return resultList;
    }

    private void dfsFunc(int index, int[] tempArray, int[] nums, boolean[] hasAccessFlagArray, List<List<Integer>> resultList) {
        if (index == nums.length) {
            List<Integer> subItemList = new ArrayList<>();
            for (int i = 0; i < nums.length; i++) {
                subItemList.add(tempArray[i]);
            }
            resultList.add(subItemList);
        }
        for (int i = 0; i < nums.length; i++) {
            if (!hasAccessFlagArray[i]) {
                hasAccessFlagArray[i] = true;
                tempArray[index] = nums[i];
                dfsFunc(index + 1, tempArray, nums, hasAccessFlagArray, resultList);
                hasAccessFlagArray[i] = false;
            }
        }
    }
}