leetcode 46 47 全排列2 Java
阿新 • • 發佈:2018-12-20
思路
46題主要是用遞迴的方法,從左到右遍歷陣列,依此將該下標和後面的數字兩兩交換,然後繼續遞迴下去,並用一個變數start記錄當前下標。直到start越過陣列下標(nums.length())時結束。
47題主要是比46題要多一個判斷重複的處理,47題的程式碼中比46題的只多了幾行,比如對2,2,1,1,要確保第一個元素2只和1個2交換,只和1個1交換(注意它和它自己交換也算一次交換)
程式碼如下:
46題
//46 領先98%以上 List<List<Integer>> res = new ArrayList<>(); public List<List<Integer>> permute(int[] nums) { res.clear(); dfs(nums, 0);// return res; } public void dfs(int[] n, int start) {//start表示要被替換元素的位置 if( start >= n.length) { List<Integer> list = new ArrayList<Integer>(); for(int i : n) { list.add(i); } res.add(list); return; } for(int i = start; i< n.length; i++) {//i從start開始,如果從start+1開始的話,會把當前序列遺漏掉直接儲存了下一個序列 int temp= n[i]; n[i] = n[start]; n[start] = temp; dfs(n, start + 1);//遞迴下一個位置 //回到上一個狀態 n[start] = n[i]; n[i] = temp; } }
47題
//47題 領先43% List<List<Integer>> res = new ArrayList<>(); public List<List<Integer>> permuteUnique(int[] nums) { res.clear(); dfs2(nums, 0);// return res; } public void dfs2(int[] n, int start) {//start表示要被替換元素的位置 if( start == n.length) { List<Integer> list = new ArrayList<Integer>(); for(int i=0; i<n.length;i++) { list.add(n[i]); } res.add(list);//有重複元素時 //可以利用下面這種方式去重,但是速度很慢 // if( !res.contains(list)) { // res.add(list); // } return; } //如果後面有重複的元素,要確保只和最多1個1交換,最多隻和1個2交換,...... Set<Integer> set = new HashSet<Integer>(); for(int i = start; i< n.length; i++) {//i從start開始,如果從start+1開始的話,會把當前序列遺漏掉直接儲存了下一個序列 if(set.contains(n[i])) { continue; } set.add(n[i]);//如果不包含的話,設定訪問過 int temp= n[i]; n[i] = n[start]; n[start] = temp; dfs2(n, start + 1);//遞迴下一個位置 //回到上一個狀態 n[start] = n[i]; n[i] = temp; } }