回溯法解決排列組合問題
package 演算法和資料結構;
/**
* Filename : Backtracking.java
* Author : [email protected]
* Creation time : 上午10:16:04 - 2017年3月13日
* Description : 利用回溯法來解決諸如 子集數量,排列,組合 的問題。
*/
import java.util.*;
public class Backtracking {
/**
* Subsets
*/
//**********************************************************************
//Subsets : https://leetcode.com/problems/subsets/
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
Arrays.sort(nums);
backtrack(list, new ArrayList<>(), nums, 0);
return list;
}
private void backtrack(List<List<Integer>> list , List<Integer> tempList, int [] nums, int start){
list.add(new ArrayList<>(tempList));
for(int i = start; i < nums.length; i++){
tempList.add(nums[i]);
backtrack(list, tempList, nums, i + 1);
tempList.remove(tempList.size() - 1 );
}
}
//********************************************************************
//Subsets II (contains duplicates) : https://leetcode.com/problems/subsets-ii/
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
Arrays.sort(nums);
backtrack2(list, new ArrayList<>(), nums, 0);
return list;
}
private void backtrack2(List<List<Integer>> list, List<Integer> tempList, int [] nums, int start){
list.add(new ArrayList<>(tempList));
for(int i = start; i < nums.length; i++){
if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates
tempList.add(nums[i]);
backtrack(list, tempList, nums, i + 1);
tempList.remove(tempList.size() - 1);
}
}
/**
* Permutations排列
*/
//***************************************************************************
//Permutations : https://leetcode.com/problems/permutations/
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
// Arrays.sort(nums); // not necessary
backtrack(list, new ArrayList<>(), nums);
return list;
}
private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums){
if(tempList.size() == nums.length){
list.add(new ArrayList<>(tempList));
} else{
for(int i = 0; i < nums.length; i++){
if(tempList.contains(nums[i])) continue; // element already exists, skip
tempList.add(nums[i]);
backtrack(list, tempList, nums);
tempList.remove(tempList.size() - 1);
}
}
}
//*******************************************************************************************
//Permutations II (contains duplicates) : https://leetcode.com/problems/permutations-ii/
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
Arrays.sort(nums);
backtrack(list, new ArrayList<>(), nums, new boolean[nums.length]);
return list;
}
private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, boolean [] used) {
if(tempList.size() == nums.length){
list.add(new ArrayList<>(tempList));
} else {
for(int i = 0; i < nums.length; i++){
if(used[i] || i > 0 && nums[i] == nums[i-1] && !used[i - 1]) continue;
used[i] = true;
tempList.add(nums[i]);
backtrack(list, tempList, nums, used);
used[i] = false;
tempList.remove(tempList.size() - 1);
}
}
}
/**
* 組合
*/
//****************************************************************************
//Combination Sum : https://leetcode.com/problems/combination-sum/
public List<List<Integer>> combinationSum(int[] nums, int target) {
List<List<Integer>> list = new ArrayList<>();
Arrays.sort(nums);
backtrack(list, new ArrayList<>(), nums, target, 0);
return list;
}
private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){
if(remain < 0) return;
else if(remain == 0) list.add(new ArrayList<>(tempList));
else{
for(int i = start; i < nums.length; i++){
tempList.add(nums[i]);
backtrack(list, tempList, nums, remain - nums[i], i); // not i + 1 because we can reuse same elements
tempList.remove(tempList.size() - 1);
}
}
}
//Combination Sum II (can't reuse same element) : https://leetcode.com/problems/combination-sum-ii/
public List<List<Integer>> combinationSum2(int[] nums, int target) {
List<List<Integer>> list = new ArrayList<>();
Arrays.sort(nums);
backtrack2(list, new ArrayList<>(), nums, target, 0);
return list;
}
private void backtrack2(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){
if(remain < 0) return;
else if(remain == 0) list.add(new ArrayList<>(tempList));
else{
for(int i = start; i < nums.length; i++){
if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates
tempList.add(nums[i]);
backtrack(list, tempList, nums, remain - nums[i], i + 1);
tempList.remove(tempList.size() - 1);
}
}
}
//Palindrome Partitioning : https://leetcode.com/problems/palindrome-partitioning/
public List<List<String>> partition(String s) {
List<List<String>> list = new ArrayList<>();
backtrack(list, new ArrayList<>(), s, 0);
return list;
}
public void backtrack(List<List<String>> list, List<String> tempList, String s, int start){
if(start == s.length())
list.add(new ArrayList<>(tempList));
else{
for(int i = start; i < s.length(); i++){
if(isPalindrome(s, start, i)){
tempList.add(s.substring(start, i + 1));
backtrack(list, tempList, s, i + 1);
tempList.remove(tempList.size() - 1);
}
}
}
}
public boolean isPalindrome(String s, int low, int high){
while(low < high)
if(s.charAt(low++) != s.charAt(high--)) return false;
return true;
}
}
相關推薦
回溯法解決排列組合問題
package 演算法和資料結構; /** * Filename : Backtracking.java * Author : [email protected] * Creation time : 上午10:16:04 - 2017年3月13日 *
用回溯法解決圓排列問題
教材是用的王曉東的《計算機演算法設計與實現》第四版,c++版一下是問題描述:演算法實現:/***能確定一個正確的想法(即每種情況都能考慮到,然後找一個最簡單而準確的方式表達出來) ***/ #include<iostream>//此問題沒有要求相鄰的圓必須相切 #
遞歸回溯法解決八皇后問題
一、八皇后問題 皇后是國際象棋中威力最大的棋子。她可以攻擊同一行、同一列以及與她處在斜線上的棋子。八皇后問題在1848年由國際西洋棋棋手馬克斯·貝瑟爾提出:如何在8x8格的棋盤上擺放八個皇后,使她們不能互相攻擊? 上圖是92種擺法中的其中一種。 一個有用的經驗是:在正式
第一次上傳程式碼 處女秀-回溯法解決八皇后問題
c語言 # include<stdio.h> # include<math.h> # define max 8 int queen[max],sum=0; int check(int n){ int i; for(i=0;i<n;i+
回溯法解決N皇后問題
八皇后問題 在棋盤上放置8個皇后,使得它們互不攻擊,此時每個皇后的攻擊範圍為同行同列和同對角線,要求找出所有解。 遞迴函式將不再遞迴呼叫它自身,而是返回上一層呼叫,這種現象稱為回溯(backtracking)。 當把問題分成若干步驟並遞迴求解時,如果當前步驟沒有合法選擇,則函式將返回
回溯法解決01揹包問題
回溯法 回溯法是一種非常有效的方法,有“通用的解題法”之稱。它有點像窮舉法,但是更帶有跳躍性和系統性,他可以系統性的搜尋一個問題的所有的解和任一解。回溯法採用的是深度優先策略。 回溯法在確定瞭解空間的結構後,從根結點出發,以深度優先的方式搜尋整個解空間,此時根結點成為一個活結點,並且
演算法題(二十一):回溯法解決矩陣路徑問題
題目描述 請設計一個函式,用來判斷在一個矩陣中是否存在一條包含某字串所有字元的路徑。路徑可以從矩陣中的任意一個格子開始,每一步可以在矩陣中向左,向右,向上,向下移動一個格子。如果一條路徑經過了矩陣中的某一個格子,則之後不能再次進入這個格子。 例如 a b c e s f c s a d e
回溯法解決N皇后問題(以四皇后為例)
回溯法解決N皇后問題(以四皇后為例) 其他的N皇后問題以此類推。所謂4皇后問題就是求解如何在4×4的棋盤上無衝突的擺放4個皇后棋子。在國際象棋中,皇后的移動方式為橫豎交叉的,因此在任意一個皇后所在位置的水平、豎直、以及45度斜線上都不能出現皇后的棋子,例子 要求程式設計求出符合要求的情
【資料結構與演算法】回溯法解決裝載問題
回溯法解決裝載問題(約束函式優化) 解題思想 遍歷各元素,若cw+w[t]<=c(即船可以裝下),則進入左子樹,w[t]標記為1,再進行遞迴,若cw+r>bestw(即當前節點的右子樹包含最優解的可能),則進入右子樹,否則,則不遍歷右子樹。 完整程式碼實現如下 p
【資料結構與演算法】回溯法解決N皇后問題,java程式碼實現
N皇后問題 問題描述 在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法,這稱為八皇后問題。 延伸一下,便為N皇后問題。 核心思想 解決N皇后問題有兩個關鍵點。一是如何進行放置棋子,二是如何驗證棋子是否符合
回溯法解決工作分配問題及分析
1、實踐題目 工作分配問題 2、問題描述 設有n件工作分配給n個人。將工作i分配給第j個人所需的費用為cij 。 設計一個演算法,對於給定的工作費用,為每一個人都分配1 件不同的工作,並使總費用達到最小。 輸入格式:輸入資料的第一行有1 個正整數n (1≤n≤20)。接下來的n行,每行n個數,表示工作
python解決排列組合問題的4種方式
前言 排列組合問題在是演算法中很基礎的一個問題,它們的區別就是,排列要考慮順序,組合不考慮順序。在面試的過程中可能會考到,在現實生活中也是經常可以遇到的,比如說一個3位數字的密碼鎖,要嘗試多少次才能解開?那麼用py
回溯法解決N後問題(java描述)
1.問題描述: N後問題就是在一個N*N的棋盤上放置N個皇后,要求這N個皇后中的任何兩個皇后不在同一行或同一列或同一斜線上。 2.演算法設計: 使用x[1...n]來表示問題的解。x[i]表示第i個皇后放在棋盤的第i行第x[i]列。因為i是唯一的,所以i是不可能相同的,所以在判斷皇后
回溯法解決八皇后(c++)
八皇后問題是一個以國際象棋為背景的問題:如何能夠在 8×8 的國際象棋棋盤上放置八個皇后,使得任何一個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行、縱行或斜線上。八皇后問題可以推廣為更一般的n皇后擺放問題:這時棋盤的大小變為n1×n1,而皇后個數也變成n2。而且僅當
插板法(排列組合)
轉自(http://www.cnblogs.com/justPassBy/p/4600772.html) 插板法的條件() (1)每個元素都是相同的 (2)分成的組,每組的元素不為空 就比如下面這個例子,分出來的組的元素是不為空的 原始問題: 將10個相同的球放到3個不同的籃子裡面去,
用回溯法解決八皇后問題的思路,並求出17皇后解的數量(c#,c++,python表示)
1.解決思路借用網上一張圖,中間那個紅點表示的就是皇后,這圖的意思也就是一個皇后的影響範圍為這這個皇后所在的那一列,那一行,對角線以及次對角線。其它的皇后不能在它的影響範圍裡否則會衝突。八皇后也就是在一個8x8的棋盤上後置8個皇后,皇后的數量與棋盤的行列數一樣。這是基礎,再來
回溯法解決素數環
/*********************************************************************** 輸入正整數n,把整數1,2,3……,n組成一個環,使得相鄰兩個整數之和均為素數,輸出時從整數1開始逆時針排序.同一個環應恰好輸
使用回溯法解決八皇后問題(同樣適用於N皇后)。
在學習資料結構的時候,看到了一道八皇后的問題。寫完後,再去網上檢視發現原來這個問題有這麼多的優化解法,相比之下相形見絀。但我還是記錄下來,有興趣的小夥伴可以看看。 先大致說下我的思路 建立一個初始化值為0的8x8的陣列,0代表無皇后且不在其他
回溯法解決0-1揹包問題
問題描述: 有n件物品和一個容量為c的揹包。第i件物品的價值是v[i],重量是w[i]。求解將哪些物品裝入揹包可使價值總和最大。所謂01揹包,表示每一個物品只有一個,要麼裝入,要麼不裝入。 回溯法: 01揹包屬於找最優解問題,用回溯法需要構造解的子
回溯法解決2n皇后(8皇后)問題
8皇后問題是演算法入門的經典,在8*8的國際象棋上擺放八個皇后,使其不能相互攻擊,即任意兩個皇后都不能處於同一 今天要說的2n皇后問題與傳統的8皇后問題有些不同,在一個n*n的棋盤中,有些位置不允許放皇后,現在要向棋盤中 放入n個黑皇后和n個白皇后,使任意的兩個黑白皇后