题目:
输入一个字符串,如"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个字符
}
};