用DFS(廣度優先遍歷)解決排列問題

2021-09-03 08:44:13 字數 1474 閱讀 5670

例如有 三個字元,求解所有由這三個字元排列得到的字串。

解題思路:

一次排列中已經遍歷過的元素不能重複遍歷,因此需要對新增過的元素進行標記,避免本次排列出現重複。

這種問題在一次排列求解完成之後還需要繼續求解,在本次排列結束後,為了保證已經訪問過但是不在當前遞迴鏈中的元素可以繼續被訪問,需要對這個元素取消標記,同時移出子集。

leetcode經典應用題目:

46 排列

[1,2,3] 有以下排列方式:

[1,2,3],

[1,3,2],

[2,1,3],

[2,3,1],

[3,1,2],

[3,2,1]

public list> permute(int nums) 

private void backtracking(listpermutelist, list> permutes, boolean visited, final int nums)

for (int i = 0; i < visited.length; i++)

visited[i] = true;

permutelist.add(nums[i]);

backtracking(permutelist, permutes, visited, nums);

permutelist.remove(permutelist.size() - 1);

visited[i] = false;

}}

leetcode變種題目:

47 含有相同元素求排列

[1,1,2] 有以下排列方式:

[[1,1,2], [1,2,1], [2,1,1]]

陣列元素可能含有相同的元素,進行排列時就有可能出現重複的排列,要求重複的排列只返回乙個。

在實現上,和 permutations 不同的是要先排序,然後在新增乙個元素時,判斷這個元素是否等於前乙個元素,如果等於,並且前乙個元素還未訪問,說明這個元素與之前的元素計算得出的組合方式是相同的,因此就跳過這個元素。

public list> permuteunique(int nums) 

private void backtracking(listpermutelist, list> permutes, boolean visited, final int nums)

for (int i = 0; i < visited.length; i++)

if (visited[i])

visited[i] = true;

permutelist.add(nums[i]);

backtracking(permutelist, permutes, visited, nums);

permutelist.remove(permutelist.size() - 1);

visited[i] = false;

}}

用DFS(廣度優先遍歷)解決組合問題

從元素集中選取幾個元素構成子集,求解可以構成子集的數目,與排列的主要區別是子集中元素順序不同視為同乙個子集 解題思路 解題時要注意進行剪枝處理,與排列問題解法的區別是對每次迭代要重新設定起始值,避免出現新增了之前的元素造成順序不同的同乙個子集被新增到答案中的情況。如果沒有重複元素,不需要用陣列對訪問...

廣度優先遍歷(一) 全排列

前言 廣度優先遍歷 回溯減枝 本質上都是樹 決策樹 的遍歷。回溯演算法框架 leetcode 46.全排列 原題鏈結 給定乙個 沒有重複 數字的序列,返回其所有可能的全排列。示例 輸入 1,2,3 輸出 1,2,3 1,3,2 2,1,3 2,3,1 3,1,2 3,2,1 分析 這道題有多種不同的...

用廣度優先搜尋方法解決放置炸彈遊戲

炸彈遊戲規則 在乙個n n的方陣裡,每乙個方格分別代表空地,敵人,牆,三種元素的分布為隨機分布,現在玩家要從地圖的某乙個空地 已知座標點 出發,走到乙個空地上放置炸彈,炸彈可以炸毀該點對應行列上的所有敵人,但是炸彈不能炸穿牆,要求的是玩家在哪乙個點放置炸彈能夠炸掉最多敵人,最多炸幾個?注意 必須考慮...