【探索-中級演算法】全排列
前提:沒有重複數字的序列
解法一:
List<List<Integer>> result = new ArrayList<>();
public List<List<Integer>> permute(int[] nums) {
boolean[] map = new boolean[nums.length];
dfs(nums, map, new ArrayList<>());
return result;
}
public void dfs(int[] nums, boolean[] visited, List<Integer> tmp) {
if (tmp.size() == nums.length)
result.add(new ArrayList<>(tmp));
else {
// 否則,開始迴圈遍歷,按照0,1,2..的順序依次選擇起點,然後遍歷
for (int i = 0; i < nums.length; i++) {
if (visited[i])// 若該點已經被訪問過了,則跳過訪問下一個點
continue;
else {
// 若沒被訪問過,那麼先標記為訪問了,然後將其加入 tmp 中,
//等得到一個全排列的結果時加入到 result 中
visited[i] = true;
tmp.add(nums[i]);
dfs(nums, visited, tmp);// 遞迴呼叫
// 遞迴結束,還原當前位置的狀態(即回溯),使得可以填充下一個元素,
// 從而進行新的組合
tmp.remove (tmp.size() - 1);
// 訪問標記還原,使得下次遍歷還可以使用該元素
visited[i] = false;
}
}
}
}
例如:對於 [1,2,3]
,有如下部分過程示例
dfs(mums, visited, tmp())
i = 0: v[0] = true
tmp = (1)
dfs(mums, visited, tmp(1))
i = 0: continue
i = 1: v[1] = true
tmp = (1, 2)
dfs(mums, visited, tmp(1, 2))
i = 0: continue
i = 1: continue
i = 2: v[2] = true
tmp = (1, 2, 3)
dfs(mums, visited, tmp(1, 2, 3))
add to result list
after tmp.remove(3 -1) tmp = (1, 2)
v[2] = false
loop end
// 遞迴結束,還原 tmp[1],去掉 tmp(1, 2) 的第二個元素
// 即回溯,得到 tmp = (1),使得 tmp[1] 位置可以填充下一個元素
after tmp.remove(2 -1) tmp = (1)
v[1] = false
i = 2: v[2] = true
...
解法二:
交換解法,核心部分就是將各個位都與後面的每一個位都交換一次,並且這種交換是累積式的
public List<List<Integer>> permute(int[] nums) {
helper(nums, 0);
return result;
}
public void helper(int[] nums, int i){
// 找到轉置完成後的解,將其存入列表中
if(i == nums.length - 1){
List<Integer> list = new LinkedList<Integer
for(int j = 0; j < nums.length; j++){
list.add(nums[j]);
}
result.add(list);
}
// 將當前位置的數跟後面的數交換,並搜尋解
for(int j = i; j < nums.length; j++){
swap(nums, i, j);// 交換位置
helper(nums, i + 1);
swap(nums, i, j);// 還原前面交換的位置
}
}
private void swap(int[] nums, int i, int j){
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
相關推薦
【探索-中級演算法】全排列
前提:沒有重複數字的序列 解法一: List<List<Integer>> result = new ArrayList<>(); public List<
【探索-中級演算法】遞增的三元子序列
最先想到的思路,就是用一個 Map<Integer, List<Integer>>,其中 key 對應下標 index,value 為當 index_x > index 時,如果 nums[index_x] > nums[index],則將
【探索-中級演算法】最長迴文子串
這一題可以參考:647. 迴文子串 本質上是一樣的,要判斷出所有的迴文字串,然後找到其中最長的那一個。 中心擴充套件法 中心擴充套件就是把給定的字串的每一個字母當做中心,向兩邊擴充套件,這樣來找最長的子迴文串。演算法複雜度為O(N^2) public Stri
【探索-中級演算法】無重複字元的最長子串
1. 參考自:https://juejin.im/post/5aa159f86fb9a028bb189420 思路: 初始化一個 255 的 boolean 陣列(字元對應的數字作為陣列下標)作為所有可能出現的字元對應的存在可能性,不存在重複的均為 false,存在重
【探索-中級演算法】字謎分組
解題的關鍵思想就是將字串建立起無關於字母順序,只關於字母個數的唯一對映關係,這樣 ,對於同一組符合要求的字串,則它們的對映都是一樣的,以此作為分組的依據。 具體的解題方法,暫時想到了兩種。 1、將字串對映為字母+數字的組合,如 a1b2c3,這樣是符合上述條件的。
【探索-中級演算法】矩陣置零
參考連結:https://www.jianshu.com/p/d0017b1e38c4 原地演算法:一種使用小的,固定數量的額外之空間來轉換資料的演算法。 當演算法執行時,輸入的資料通常會被要輸出的部份覆蓋掉。 O(mn) 的額外空間 public void se
【探索-中級演算法】三數之和
參考連結:LeetCode總結-K-Sum問題 本文介紹的解題思想的核心就是排序,排序有兩個目的,第一個是次要的,即方便排除重複的組合。第二個就是使得可以按照遞增或者遞減方便的移動指標 l、r。 在排序之後,就可以對陣列進行遍歷,目標就是找到符合 nums[l] +
【探索-中級演算法】兩數相加
public ListNode addTwoNumbers(ListNode l1, ListNode l2) { if (l1==null) return l2; else if (l2==null) return l1; Li
【探索-中級演算法】生成括號
得到全排列的組合,同時對於不符合要求的組合要剔除。 public List<String> generateParenthesis(int n) { List<String> result = new ArrayList<>();
【探索-中級演算法】相交連結串列
注意題目要求的時間與空間複雜度。 只要保持交點之前移動的距離相等即可。即在遍歷 A、B 的時候要同時從 a1 和 b2 開始,這樣才能保證同時遍歷到相交的 c1。 public ListNode ge
【探索-中級演算法】單詞搜尋
解法一 遞迴 結合回溯與深搜,因同一單元格不能被重複使用,因此藉助一個輔助陣列用於記錄單元格是否被訪問過。 需要剪枝的策略: 1.當前元素與單詞的對應位置的字母不一致 2.當前元素已經被遍歷過 3.超出了 borad 的邊界 public boolean e
【探索-中級演算法】顏色分類
初級解法一 首先,使用最簡單的解法,可以拆分成兩步。 第一步:掃描陣列,先把 0 放在最前面,把 1 和 2 放在最後面(即使是混淆的也沒關係)。 第二步:再在混淆的 1 和 2 中進行排序。 每一步的排序,都需要藉助兩個指標。 public void sor
【探索-中級演算法】島嶼的個數
最開始想到的解決方法,就是藉助一個輔助陣列 boolean[][] map,其中 map[i][j]==true 表示該土地已經被訪問過了,且再借助深度遍歷,當遇到一塊土地時,同時把與其相連的土地都給
5972: 【遞歸入門】全排列
ans nbsp 學習 lag amp spa include print 入門經典 題目描述 排列與組合是常用的數學方法。 先給一個正整數 ( 1 < = n < = 10 ) 例如n=3,所有組合,並且按字典序輸出: 1 2 3 1 3 2
【演算法 in python】全排列
1.全排列 給定一個沒有重複數字的序列,返回其所有可能的全排列 #遞迴,取一個數放在第一個位置,然後求剩下資料的全排列,以此類推 class Solution: def permute(self, nums): """ :type nums: List
【DFS】全排列問題
題目 輸出自然數 1 到 n 所有不重複的排列,即 n 的全排列,要求所產生的任一數字序列中不允許出現重複的數字。 輸入 n(1≤n≤9) 輸出 由 1~n 組成的所有不重複的數字序列,每行一個序列。 樣例輸入#1 3 樣例輸出#2 1 2 3 1 3 2
【演算法】求全排列 回溯 交換 DFS JAVA
思路簡述: 一個全排列其實就是一條把陣列無重複遍歷一遍的DFS過程 思路一:簡單回溯, 1. 一個List存遍歷路徑,從第N個“結點”到第N+1個“結點”是隻需要找一個未遍歷的結點就行 2. 一個關鍵點在於查詢 下一個可遍歷“結點”, 可以用SET輔助List存放已遍歷結點
【java】全排列 列舉子集
全排列: 輸入一個包含n個字元的字串,輸出該字串的全排列。 樣例輸入: abc ab 樣例輸出: abc acb bac bca cab cba ab ba import java.util.Sca
luogu【P1706】全排列問題
思路:最近發現自己對dfs的理解不夠深透於是寫了一個最基礎的dfs然後分析了一下QwQ#include<iostream> #include<cstdio> #include&
【探索之路】機器人篇-ROS系統並創建工作空間和項目
wid 輸入 圖片 描述 wiki 創建目錄 dir osc ins 在ROS官網,已經給出了詳細的教程。下面我就般一下磚,把相應的操作寫到這裏。官方網址:http://wiki.ros.org/cn/ 安裝ROS系統 indigo在ubuntu上的安裝教程。官網: