1. 程式人生 > >劍指Offer:字串的排列

劍指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是沒選擇,不行。共有2strlen("abc")1中組合。
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:左旋轉字符串