1、全排列
將n個不同元素按照不同的順序進行排列,一般要求所有的排列方式,或者滿足某些要求的排列方式,比如先後順序的限制
2、遞迴實現全排列
eg: 對[a b c d ]進行全排列,可以按照以下的步驟:
1. a後面加上[b c d]的全排列
2. b後面加上[a c d]的全排列
3. c後面加上[b a d]的全排列
4. d後面加上[b c a]的全排列
5. 對[b c d]等的處理和上面類似,即對每乙個求全排列字串的處理都是迴圈字串中的每乙個字元作為首字元,然後將剩餘的部分作為乙個完整的字串再次對其求全排列,遞迴到底部就是當傳入的引數只有乙個字串,此時輸出,返回上一級的遞迴。
上**:
/**
* 遞迴實現全排列
**@param s 求全排列的字串(有begin,end約束的子串)
*@param begin
*@param end
*/public
static
void
premutation(string s, int begin, int end)
//對字串的每乙個字元進行迴圈,當做全排列的首字元
for (int i = begin; i <= end; i++)
}public
static string replacecharacter(string s, int begin, int i)
3、非遞迴實現全排列
即字典序全排列,基本思想是:先對需要求排列的字串進行字典排序,記得到全排列中最小的排列,然後找到乙個比它大的最小的全排列,一直重複這一步直到找到最大值(即字典排序的逆序列)
基本步驟是:
對字串進行字典排序
找到乙個最小的排列ai
找到乙個比ai大的最小的後繼排列ai+1
重複上一步直到沒有這樣的後繼
重點就是如何找到乙個排列的直接後繼。
對於字串a0a1a2……an
從an到a0尋找第一次出現的公升序排列的兩個字元,即ai< ai+1,ai+1是乙個極值,因為ai+1之後的字串為降序排列,記top=i+1
從top處開始查詢比ai大的最小的值,記為temp
交換temp和i處的字元
倒置top之後的字串(包括top),即得到了後繼的排列
**如下
/**
* 非遞迴實現全排列,字典序排列演算法
*@param s
*/public
static
void
premutation2(string s)
}int temp = top;
//2、從top開始往後查詢比ai大的最小的值的下標,或者從後往前查詢
for (int i = sb.length() - 1; i >= top; i--)
}//3、交換temp和top-1
sb = new stringbuilder(swapcharacter(sb.tostring(), temp, top - 1));
//4、從top往後倒置
sb = new stringbuilder(sb.substring(0,top) + sb.reverse().substring(0, sb.length()-top));
system.out.println(sb);}}
public
static
boolean
hasnext(stringbuilder sb)
}return hasnext;
}public
static stringbuilder sortstringbydict(string s) }}
return sortstr;
}
全排列 遞迴與非遞迴實現
全排列問題在公司筆試的時候非經常見,這裡介紹其遞迴與非遞迴實現。簡單地說 就是第乙個數分別以後面的數進行交換 e.g e a b c 則 prem e a.perm b,c b.perm a,c c.perm a,b 然後a.perm b,c ab.perm c ac.perm b abc acb....
全排列的遞迴與非遞迴實現
問題 輸入乙個序列 元素無重複 輸出其全排列 一般採用經典的遞迴解法,後來想將其改造為非遞迴 思考很久後覺得並不好寫,手工模擬遞迴棧的行為容易出錯。然後上網搜尋了一下眾的非遞迴 發現很多人的非遞迴 是各種全新的求解演算法,而不是相同演算法的非遞迴實現,和我想要的不一樣。遞迴解法 假設輸入序列 0,1...
全排列遞迴與非遞迴python實現
全排列就是,給定乙個序列,列舉出該序列中元素所有的排列情況,列舉方法有遞迴和非遞迴兩種,詳細可以見這位大神寫的部落格 我只列出來兩個重要的圖吧。1.非遞迴 字典序法 如下圖 1,2,3 的例子 2.遞迴方法 遞迴方法就是將序列中第一位固定,然後將後面n 1為的全排列列舉出來,取遍第一位所有取值,遞迴...