劍指Offer:字串的排列
輸入一個字串,打印出該字串中字元的所有排列。例如輸入字串“abc”,則打印出由a、b、c所能排列出來的所有字串abc、acb、bac、bca、cab和cba。
我們解這題時可以將字串劃分為兩部分:首字元和後面的所有字元。
首先求所有可能出現在第一個位置的字元,即把首字元和後面的字元交換。
下圖是字串abc所有字元出現在第一個位置的情形:
然後對後面部分的字串進行第一步操作:
很容易想到使用遞迴去解決這個問題。
程式碼實現:
//pos:首字元的所在位置
private static void Permutation(char[] chs,int pos){
if(chs==null ){
return;
}
if(pos==chs.length-1){
System.out.println(chs);
return;
}
for(int i=pos;i<chs.length;i++){
//首部字元和它後面的字元(包括自己)進行交換
char temp = chs[i];
chs[i] = chs[pos];
chs[pos] = temp;
//遞迴求後面的字元的排列
Permutation(chs,pos+1 );
//由於前面交換了一下,所以chs的內容改變了,我們要還原回來
temp = chs[i];
chs[i] = chs[pos];
chs[pos] = temp;
}
}
本題拓展:
如果不是求字元的所有排列,而是求字元的所有組合,應該怎麼辦呢? 還是輸入三個字元 a、b、c,則它們的組合有 a、b、c、ab、ac、be、abc。 當交換字串中的兩個字元時,雖然能得到兩個不同的排列,但卻是同一個組合。比如 ab 和 ba 是不同的排列,但只算一個組合。
如果輸入 n 個字元,則這 n 個字元能構成長度為 1 的組合、長度為 2 的組合、….、長度為 n 的組合。在求 n 個字元的長度為 m ( 1<=m<=n) 的 組合的時候,我們把這 n 個字元分成兩部分:第一個字元和其餘的所有字元。如果組合裡包含第一個字元,則下一步在剩餘的字元裡選取 m-1個字 符:如果組合裡不包含第一個字元,則下一步在剩餘的 n-1 個字元裡選取 m 個字元。也就是說,我們可以把求 n 個字元組成長度為 m 的組合的問題分解成兩個子問題,分別求 n-1 個字串中長度為 m-1 的組合,以及求 n-1 個字元的長度為 m 的組合。這兩個子問題都可以用遞迴的方式解決。
實現程式碼:
private static void Combination(char[] chs,int m,int pos,List<Character> list){
if(chs==null){
return;
}
if(m==0){
System.out.println(list.toString());
return;
}
if(pos==chs.length){
return;
}
//選擇首字元
list.add(chs[pos]);
Combination(chs,m-1,pos+1,list);
//不選擇首字元
list.remove((Character)chs[pos]);
Combination(chs,m,pos+1,list);
}
測試:
public static void main(String[] args) {
System.out.print("Please input string:");
String str = new Scanner(System.in).next();
char[] chs = str.toCharArray();
List list = new ArrayList<Character>();
for(int m=1;m<=chs.length;m++){
Combination(chs,m,0,list);
}
}
除了這種解法還要一種解法—–點陣圖法。
譬如選擇表示為“1”,不選擇表示為“0”,那麼abc的組合方法有:001(a),010(b),011(ab),100(c),101(ac),110(cb),111(abc)。000是沒選擇,不行。共有中組合。
C語言實現程式碼,java類似:
#include<stdio.h>
#include<string.h>
void Combination(char *str)
{
if(str == NULL)
return ;
int len = strlen(str);
int n = 1<<len;//1左移len位,求得的n表示共有幾種組合
int i=1;
int j=0;
for(i=1;i<n;i++) //從 1 迴圈到 2^len -1
{
for(j=0;j<len;j++)
{
int temp = i;
if(temp & (1<<j)) //對應位上為1,則輸出對應的字元
{
printf("%c",*(str+j));
}
}
printf("\n");
}
}
void main()
{
char str[] = "abc";
Combination(str);
}
相關推薦
劍指Offer:字串的排列
輸入一個字串,打印出該字串中字元的所有排列。例如輸入字串“abc”,則打印出由a、b、c所能排列出來的所有字串abc、acb、bac、bca、cab和cba。 我們解這題時可以將字串劃分為兩部分:首字元和後面的所有字元。 首先求所有可能出現在第一個位置的字元
劍指offer:字串的全排列
輸入一個字串,按字典序打印出該字串中字元的所有排列。例如輸入字串abc,則打印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。 輸入描述: 輸入一個字串,長度不超過9(可能有字元重複),字元只包括大小寫字母。 class Solution { public:
劍指Offer:字串替換問題
題目描述 請實現一個函式,將一個字串中的每個空格替換成“%20”。例如,當字串為We Are Happy.則經過替換之後的字串為We%20Are%20Happy。 解題思路 因為使用C++語言描述,所以replaceSpace函式中的length為char陣列最
劍指Offer38:字串的排列
題目: 輸入一個字串,打印出該字串中字元的所有排列。 例如:輸入字串abc,則打印出由字元a、b、c所能排列出來的所有字串abc、acb、bac、bca、cab、cba 分析:可將字串分為兩部分,第一部分是第一個字元,第二部分是其他。 依此向下挪動第一個字元,第一個字元與其他不一樣的字元
[劍指offer] --27.字串的排列
題目描述 輸入一個字串,按字典序打印出該字串中字元的所有排列。例如輸入字串abc,則打印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。 輸入描述: 輸入一個字串,長度不超過9(可能有字元重複),字元只包括大小寫字母。 import java.
【python資料結構與演算法】【劍指offer】字串的排列
題目描述: 輸入一個字串,按字典序打印出該字串中字元的所有排列。例如輸入字串abc,則打印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba,且要求輸出字串按序排列,不可重複 思路: 其實排列問題的思路很簡單,有點類似《劍指offer
【劍指offer】字串的全排列
題目描述 輸入一個字串,按字典序打印出該字串中字元的所有排列。例如輸入字串abc,則打印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。 輸入描述 輸入一個字串,長度不超過9(可能有字元重複),字元只包括大小寫字母。 注意有可能重
(劍指offer)字串的排列
時間限制:1秒 空間限制:32768K 熱度指數:284134 本題知識點: 字串 題目描述 輸入一個字串,按字典序打印出該字串中字元的所有排列。例如輸入字串abc,則打印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。 輸入描述: 輸入一個字
劍指offer:左旋轉字串
# -*- coding:utf-8 -*- class Solution: def LeftRotateString(self, s, n): # write code here if s=='': retur
劍指offer——27.字串的排列
題目描述: 輸入一個字串,按字典序打印出該字串中字元的所有排列。例如輸入字串abc,則打印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。 輸入描述:輸入一個
劍指Offer30:字串的排列
思路: 程式碼是借鑑其他大佬的,就當做學習,遞迴總是有點不太行。 class Solution: def Permutation(self, ss): if len(ss) <=0: return [] res = lis
【劍指offer】字串的排列
題目描述 輸入一個字串,按字典序打印出該字串中字元的所有排列。例如輸入字串abc,則打印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。 輸入描述: 輸入一個字串,長度不超過9(可能有字元重複),字元只包括大小寫字母。 class
劍指offer:第49題字串轉化成整型(題目要求:不要用轉換函式)
思路:拆分在合併,有非數字符號的return 0; public class _Test49 { public static void main(String[] args) { Scanner scanner = new Scanner
劍指Offer.38 字串全排列(包含重複)
題目給定字串“abca”輸出其全部排列。分析:package 劍指Offer; import java.util.ArrayList; import java.util.List; public c
《劍指offer》——字串的排列
T: 題目描述 輸入一個字串,按字典序打印出該字串中字元的所有排列。例如輸入字串abc,則打印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。 結果請按字母順序輸出。 輸入描述: 輸
劍指offer:表示數值的字串(Python)
題目描述 請實現一個函式用來判斷字串是否表示數值(包括整數和小數)。例如,字串”+100”,”5e2”,”-123”,”3.1416”和”-1E-16”都表示數值。 但是”12e”,”1a3.14”,”1.2.3”,”+-5”和”12e+4.3”都不是。 解
【劍指offer】字串的排列與組合
【1、字串排列】 【題目】 輸入一個字串,按字典序打印出該字串中字元的所有排列。例如輸入字串abc,則打印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。
【劍指Offer】字串全排列
題目描述 輸入一個字串,按字典序打印出該字串中字元的所有排列。例如輸入字串abc,則打印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。 輸入描述 輸入一個字串,長度不超過9(可能有字元重複),字元只包括大小寫字
劍指offer:數組中出現次數超過一半的數字
一次 相同元素 log 由於 個數字 csdn tail 第一個 可能 http://blog.csdn.net/qq_27703417/article/details/70948850 數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度為9
劍指offer:左旋轉字符串
字符串 logs src blog 技術分享 ges 旋轉 技術 com 劍指offer:左旋轉字符串