1. 程式人生 > >回溯法解決排列組合問題

回溯法解決排列組合問題

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個白皇后,使任意的兩個黑白皇后