演算法45--回溯法2--Permutations,Permutations2
Given a collection of distinct integers, return all possible permutations.
Example:
Input: [1,2,3] Output: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
利用回溯法來解決,考慮每一位可能出現的數字 第一位是nums所有元素都有可能,第二位是除去第一位的所有元素,用r來儲存一個臨時結果,依次考慮r的每一位,每一位都要從nums所有元素進行遍歷,當r中已有該元素時,則跳過進行下一個元素的遍歷,當len(r)==len(nums)時,將此時的r儲存到rr中,刪除r的最後一個元素,進行最後一個元素的下一種可能的遍歷。
class Solution: def permute(self, nums=[1,2,3]): """ :type nums: List[int] :rtype: List[List[int]] """ rr = [] nums.sort() self.backtrace(rr, [], nums) return rr def backtrace(self, rr, r, nums): if len(r)==len(nums): rr.append(r.copy()) return for i in range(0, len(nums)): if nums[i] in r: continue r.append(nums[i]) self.backtrace(rr, r, nums) r.pop(-1)
全排列的遞迴解法:
def swap(num, i, j): tmp = num[i] num[i] = num[j] num[j] = tmp #num無重複數字 def fullSort(num, index): if index==len(num)-1: print (num) return for i in range(index, len(num)): swap(num, index, i) fullSort(num, index+1) swap(num, index, i)
全排列的非遞迴解法: 依次產生比上一個數大的排列,直到達到最大值
#尋找比替換點大的最小數,倒序尋找,第一個大的數就是目標值
def findBiggerThanReplaceNum(num, r):
min = r
for i in range(len(num)-1, r, -1):
if num[i]>num[r]:
return i
return min
def reverse(num, i, j):
while i<j:
swap(num, i, j)
i += 1
j -= 1
def fullSort3(num):
num.sort()
print (num)
#替換數的下標 排序完成後第一個數
r = len(num)-1
#替換點的下一個數座標
m = r
while r>0:
m = r
r -= 1
#print ('r = ', r)
if num[r]<num[m]:
s = findBiggerThanReplaceNum(num, r)
#print ('s = ',s)
swap(num, r, s)
reverse(num, r+1, len(num)-1)
print (num)
#break
r = len(num)-1
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
Example:
Input: [1,1,2] Output: [ [1,1,2], [1,2,1], [2,1,1] ]
求出去重的全排列:
回溯法 依次考慮每一位的取值情況,利用flag陣列來儲存nums的每一位是否使用過,第i位數字可以跳過的條件是第i位已經使用,或者nums[i]==nums[i-1]並且第i-1位使用過
class Solution:
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
rr = []
flag = [False for v in range(len(nums))]
nums.sort()
self.backtrace(rr, [], flag, nums)
return rr
def backtrace(self, rr, r, flag, nums):
if len(r)==len(nums):
rr.append(r.copy())
return
for i in range(0, len(nums)):
if flag[i] or i>0 and nums[i-1]==nums[i] and flag[i-1]:
continue
r.append(nums[i])
flag[i] = True
print(r)
self.backtrace(rr, r, flag, nums)
r.pop(-1)
flag[i] = False
遞迴解法去重:
#num中有重複數字
def fullSort2(num, index):
if index==len(num)-1:
print (num)
return
for i in range(index, len(num)):
#print (isSwap(num, index, i))
if isSwap(num, index, i):
swap(num, index, i)
fullSort2(num, index+1)
swap(num, index, i)
def isSwap(num, index, i):
for j in range(index, i):
if num[j]==num[i]:
return False
return True
相關推薦
演算法45--回溯法2--Permutations,Permutations2
Given a collection of distinct integers, return all possible permutations. Example: Input: [1,2,3] Output: [ [1,2,3], [1,3,2], [2,
【資料結構與演算法】回溯法解決N皇后問題,java程式碼實現
N皇后問題 問題描述 在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法,這稱為八皇后問題。 延伸一下,便為N皇后問題。 核心思想 解決N皇后問題有兩個關鍵點。一是如何進行放置棋子,二是如何驗證棋子是否符合
演算法46--回溯法3--Combination Sum1,2,3,4
Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidate
01揹包問題 -- 回溯法 2
/*0-1揹包虛擬碼*/ #include <iostream> using namespace std; template<class Typew,class Typep> class Knap //Knap類記錄解空間樹的結點資訊 {
[回溯法] 2 四皇后問題
前言 回溯法 1-求n個元素的集合的冪集中狀態變化樹是一棵滿二叉樹:樹中每個葉子結點的狀態都是求解過程中可能出現的狀態(即問題的解)。 【然而】很多問題用回溯和試探求解時,描述求解過程的狀態樹不是一棵滿的多叉樹 【非滿多叉樹】不是滿的多叉樹:當試探過程中出現的狀態和問題所求解產生
【資料結構與演算法】回溯法解決裝載問題
回溯法解決裝載問題(約束函式優化) 解題思想 遍歷各元素,若cw+w[t]<=c(即船可以裝下),則進入左子樹,w[t]標記為1,再進行遞迴,若cw+r>bestw(即當前節點的右子樹包含最優解的可能),則進入右子樹,否則,則不遍歷右子樹。 完整程式碼實現如下 p
【基礎演算法】回溯法與八皇后問題
#include"iostream" #include"stdlib.h" using namespace std; int x[8],tot=0; bool B(int x[],int k) { int i; for(i=0;i<k;i++) if(x[i]==x[
演算法入門——回溯法
用淺顯的話說回溯法就是屢敗屢戰的一種精神:用走迷宮來說吧,第一次每次遇到岔路就往左走,直到走到死路就回到上一個岔路,這時候不往左了,改為往右,然後繼續一直往左走。差不多就是這樣,但是怕繞,拿過一個比喻吧:比如我要猜出你的6位數支付密碼:一開始我用000000,沒用的話我就回到5位數的時候0000
常用演算法之回溯法
思路:在包含問題的解空間中,按照深度優先搜尋的策略,從根節點出發深度探索解空間樹,當探索到某一節點時,先判斷該節點是否包含問題的解,如果包含,就從該節點觸發繼續探索下去,如果不包含該節點的解,則逐層向其祖先節點回溯。 示例 組合總和:給定一個無重複元素的陣列 candidates 和一個目標數 targe
常用演算法:分治演算法、動態規劃演算法、貪心演算法、回溯法、分支限界法
1、概念 回溯演算法實際上一個類似列舉的搜尋嘗試過程,主要是在搜尋嘗試過程中尋找問題的解,當發現已不滿足求解條件時,就“回溯”返回,嘗試別的路徑。 回溯法是一種選優搜尋法,按選優條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再
數獨求解演算法(回溯法和唯一解法)java實現
數獨(すうどく,Sudoku)是一種運用紙、筆進行演算的邏輯遊戲。玩家需要根據9×9盤面上的已知數字,推理出所有剩餘空格的數字,並滿足每一行、每一列、每一個粗線宮內的數字均含1-9,不重複。 注:數獨的各種知識和解決思路請 參考http://www.llang
[回溯演算法] 五大常用演算法之回溯法
演算法入門6:回溯法一. 回溯法 – 深度優先搜素 1. 簡單概述 回溯法思路的簡單描述是:把問題的解空間轉化成了圖或者樹的結構表示,然後使用深度優先搜尋策略進行遍歷,遍歷的過程中記錄和尋找所有可行解或者最優解。基本思想
演算法44--回溯法1--subsets,subsets2
1.Subsets Given a set of distinct integers, nums, return all possible subsets (the power set). Note: The solution set must not contain d
演算法47--回溯法4--演算法總結
之前用回溯法解決了子集,排列,組合等問題,現在總結一下回溯演算法: 在包含問題的所有解的解空間樹中,按照深度優先搜尋的策略,從根結點出發深度探索解空間樹。當探索到某一結點時,要先判斷該結點是否包含問題的解,如果包含,就從該結點出發繼續探索下去,如果該結點不包含問題的解,則逐
【演算法】回溯法四步走
# 回溯法 對於回溯法,網上有很多種解釋,這裡我依照自己的(死宅)觀點做了以下三種通俗易懂的解釋: - **正經版解釋:**其實人生就像一顆充滿了分支的n叉樹,你的每一個選擇都會使你走向不同的路線,獲得不同的結局。如果能重來,我要選李白~呸!說錯了,如果能重來,我們就能回溯到以前,選擇到最美好的結局。 -
(待解決,效率低下)47. Permutations II C++回溯法
limit gin == ++ 查找 != mys backtrack mit 思路是在相似題Permutations的基礎上,將結果放到set中,利用set容器不會出現重復元素的特性,得到所需結果 但是利用代碼中的/* */部分通過叠代器遍歷set將set中的元素放在一個
資料結構與演算法- 五大常用演算法總結(分治法,回溯法,分治限界法,貪心演算法,動態規劃法)
1.分治法(Recurrence and Divide-Conquer) 對於一個規模為n的問題,若該問題可以容易解決(比如說規模n較小)則直接解決,否則將其分解為k個規模較小的子問題,這些子問題互相獨立且與原問題形式相同,遞迴地解決這些子問
基礎練習 2n皇后問題 ——回溯法,貪心演算法
/*基礎練習 2n皇后問題問題描述 給定一個n*n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行、同一列或同一條對角線上,任意的兩個白皇后都不在同一行、同一列或同一條對角線上。問總共有多少种放法?n小於等於8。輸
求{1,2,3}的子集————回溯法(遞迴與非遞迴)
求ar[]={1,2,3}的子集序列,小夥伴們可以先自己嘗試解一下~~ #include<iostream> using namespace std; //用回溯法搜尋子集樹 void fun(int *ar,int *br,int n)//非遞迴
一個臺階總共有n 級,如果一次可以跳1 級,也可以跳2 級,求總共有多少總跳法,並分析演算法的時間複雜度。
這是華哥那天問我的,當時不想動腦。回來後,網上看了一下,原理很簡單,用到了遞迴。但我遞迴很菜。。。 他的思路是: 我們把n 級臺階時的跳法看成是n 的函式,記為f(n)。當n>2 時,第一次跳的時候就有兩種不同的選擇:一是第一次只跳1 級,此時跳法數目等於後面剩下的n