LinkedIn 面试题:字符串的全排列(Permutation)和组合(Combination)

题目:

输入一个字符串,如"abc",打印该字符串所有可能的排列,如"abc","acb","bac","bca","cab","cba"。

思路:

从字符串的第一个字符开始,如"a",分别和原字符串的各位字符做交换,如a<->a = abc, a<->b = bac, a<-> c = cba。递归。

解法:

class Solution {
public:
	void stringPermutation( string s )
	{
		
		if(!s.length())
			return;
		
		string begin;
		permutationRecursion(s, begin);
		cout << endl;
	}

	void permutationRecursion(string s, string & begin)
	{			
		if(s.length() == 1)
		{
			if(begin.length() != 0)
				cout << begin;
			
			cout << s << '\t';

			return;
		}

		char firstLetter = s[0]; 

		for(size_t i = 0; i < s.length(); i++)
		{
			swap(firstLetter, s[i]);
			begin.push_back(firstLetter);
			permutationRecursion(s.substr(1, s.length()-1), begin);
			begin.pop_back();
		}
	}
};

简化一下:

	void permutationRecursion(string & s, size_t begin)
	{			
		if(begin == s.length())
		{			
			cout << s << '\t';

			return;
		}

		for(size_t i = begin; i < s.length(); i++)
		{
			swap(s[begin], s[i]);
			permutationRecursion(s, begin+1);
			swap(s[begin], s[i]);
		}
	}

测试用例:

#include <iostream>
#include <string>

using namespace std;

int main(int argc, const char* argv[])
{
	string s = "abcde";
	Solution sol;
	sol.stringPermutation(s); 
	return 0;
}

Cracking the Code Interview的思路,由一个字符开始,第二个字符插入到第一个字符的各个可能位置,第三个字符插到前两个字符组成的排列的各个位置,以此类推,递归。

//
//  main.cpp
//  Combination
//
//  Created by FENGLINAN on 14-2-3.
//  Copyright (c) 2014年 FENGLINAN. All rights reserved.
//

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Solution {
public:
    void Combination( const string & s )
    {
        if(!s.length())
            return;
        vector<string> result;
        
        CombinationRecursion(s, 0, result);
        cout << endl;
    }
    
    void CombinationRecursion( const string & s, int begin, vector<string> temp )
    {
        if(begin == s.length())
        {
            for(size_t i = 0; i < temp.size(); i++)
                cout << temp[i] << " ";
            return;
        }
        
        if(temp.size())
        {
            vector<string> newTemp;
            for(size_t i = 0; i < temp.size(); i++)
            {
                for(size_t j = 0; j <= temp[i].length(); j++)
                {
                    newTemp.push_back(temp[i].insert(j, s.substr(begin, 1)));
                    temp[i].erase(j, 1);
                }
            }
            CombinationRecursion(s, begin+1, newTemp);
        }
        else {
            temp.push_back(s.substr(begin, 1));
            CombinationRecursion(s, begin+1, temp);
        }
    }
    
};

int main(int argc, const char * argv[])
{

    // insert code here...
    string s = "abcde";
    cout << s << endl;
    Solution a;
    a.Combination(s);
    return 0;
}



题目:

输入一个字符串,如"abc",打印该字符串所有可能的组合,如"a", "b","c", "ab", "ac","bc", "abc"。注意,求组合,"ab" = "ba",故只需打印一次。

题解:

class Solution {
public:
	void stringCombination( string s )
	{
		
		if(!s.length())
			return;
		
		for(size_t i = 1; i <= s.length(); i++)
		{
			string ahead;
			combinationRecursion(s, 0, i, ahead);
			cout << endl;
		}
		
	}

	void combinationRecursion(string & s, size_t begin, size_t len, string & ahead)
	{			
		if(begin >= s.length() && len > 0)//如果没有可供选择的字符串,而还要求选len > 0个字符,无法满足, 返回
			return;
		
		if(len <= 0) //如果不需再进行选择,打印ahead保存的选好的字符
		{
			if(ahead.length() != 0)
				cout << ahead << ' ';
			return;
		}
		

		ahead.push_back(s[begin]); //选择第一个字符
		combinationRecursion(s, begin+1, len-1, ahead); //在剩下的字符串里,选择len-1个字符
		ahead.pop_back(); //又或者不选第一个字符
		combinationRecursion(s, begin+1, len, ahead); //在剩下的字符串里,选择len个字符
	}
};


你可能感兴趣的:(Algorithm,面试题,permutation,LinkedIn,字符串排列)