日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[Leetcode][第60题][JAVA][第k个排列][回溯][DFS][剪枝]

發布時間:2023/12/10 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Leetcode][第60题][JAVA][第k个排列][回溯][DFS][剪枝] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【問題描述】[中等]

【解答思路】

1. 回溯搜索算法 + 剪枝 ,直接來到葉子結點





時間復雜度:O(N^2) 空間復雜度:O(N)

import java.util.Arrays;public class Solution {/*** 記錄數字是否使用過*/private boolean[] used;/*** 階乘數組*/private int[] factorial;private int n;private int k;public String getPermutation(int n, int k) {this.n = n;this.k = k;calculateFactorial(n);// 查找全排列需要的布爾數組used = new boolean[n + 1];Arrays.fill(used, false);StringBuilder path = new StringBuilder();dfs(0, path);return path.toString();}/*** @param index 在這一步之前已經選擇了幾個數字,其值恰好等于這一步需要確定的下標位置* @param path*/private void dfs(int index, StringBuilder path) {if (index == n) {return;}// 計算還未確定的數字的全排列的個數,第 1 次進入的時候是 n - 1int cnt = factorial[n - 1 - index];for (int i = 1; i <= n; i++) {if (used[i]) {continue;}if (cnt < k) {k -= cnt;continue;}path.append(i);used[i] = true;dfs(index + 1, path);// 注意 1:沒有回溯(狀態重置)的必要// 注意 2:這里要加 return,后面的數沒有必要遍歷去嘗試了return;}}/*** 計算階乘數組** @param n*/private void calculateFactorial(int n) {factorial = new int[n + 1];factorial[0] = 1;for (int i = 1; i <= n; i++) {factorial[i] = factorial[i - 1] * i;}} }作者:liweiwei1419 鏈接:https://leetcode-cn.com/problems/permutation-sequence/solution/hui-su-jian-zhi-python-dai-ma-java-dai-ma-by-liwei/
2. 有序數組(鏈表)模擬



時間復雜度:O(N2) 空間復雜度:O(N)

import java.util.LinkedList; import java.util.List;public class Solution {public String getPermutation(int n, int k) {// 注意:相當于在 n 個數字的全排列中找到下標為 k - 1 的那個數,因此 k 先減 1k --;int[] factorial = new int[n];factorial[0] = 1;// 先算出所有的階乘值for (int i = 1; i < n; i++) {factorial[i] = factorial[i - 1] * i;}// 這里使用數組或者鏈表都行List<Integer> nums = new LinkedList<>();for (int i = 1; i <= n; i++) {nums.add(i);}StringBuilder stringBuilder = new StringBuilder();// i 表示剩余的數字個數,初始化為 n - 1for (int i = n - 1; i >= 0; i--) {int index = k / factorial[i] ;stringBuilder.append(nums.remove(index));k -= index * factorial[i];}return stringBuilder.toString();} }作者:liweiwei1419 鏈接:https://leetcode-cn.com/problems/permutation-sequence/solution/hui-su-jian-zhi-python-dai-ma-java-dai-ma-by-liwei/

【總結】

1. 剪枝大法好 充分利用條件邊界 減少回溯
2.回溯思想

【數據結構與算法】【算法思想】回溯算法

3.常規思路超時 全排列 dfs傳遞的是深度 不是具體某一個值

相關題目
[Leedcode][JAVA][第46題][全排列][回溯算法]

class Solution {private static String str = "";public String getPermutation(int n, int k) {List<String> a =new ArrayList<String>();boolean[] used = new boolean[n];int[]num = new int[n];for(int i =0 ;i<n;i++){num[i] = i+1;}permunte(0,n,num,a,used,k,"");return str;}private void permunte(int depth, int n,int[] num, List<String> a,boolean[] used ,int k,String s){if(s.length() == n){a.add(s);if(a.size() == k){str = s;return ;}}for(int i=0;i<n;i++){StringBuffer sb = new StringBuffer(s);if(!used[i]){used[i] = true;sb.append(num[i]);permunte(depth+1,n,num,a,used,k,sb.toString());used[i] = false;sb.deleteCharAt(sb.length()-1);}}}}

轉載鏈接:https://leetcode-cn.com/problems/permutation-sequence/solution/hui-su-jian-zhi-python-dai-ma-java-dai-ma-by-liwei/

總結

以上是生活随笔為你收集整理的[Leetcode][第60题][JAVA][第k个排列][回溯][DFS][剪枝]的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。