输入一个字符串,按字典序打印出该字符串中字符的所有排列。
输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
剑指Offer(第2版):P197
#include
class Solution {
public:
vector<string> Permutation(string str) {
std::vector<string> ret;
if(str.size() == 0)
return ret;
Permutation(ret, str, 0);
sort(ret.begin(), ret.end()); //这里加sort是为了通过线上的测试
return ret;
}
// 注意递归函数中,需要传入的是数组的地址引用
void Permutation(vector<string> &array, string str, int begin){
if(begin == str.size()-1)
array.push_back(str);
for(int i=begin; i//将第一个字符和后面的交换
swap(str[i], str[begin]);
//处理后面的字符串
Permutation(array, str, begin+1);
//在处理完毕后面的字符串后,需要继续执行当前第一个字符串的交换,
//所以为了确保程序的正确执行,需要将交换的字符串还原,然后再执行后序的循环交换操作
swap(str[i], str[begin]);
}
}
};
isswap
函数来判断后面是否存在与当前元素相同的元素,如果有,则不进行交换,相当于我们只对所有重复元素中的最后一个元素进行相关操作。#include
#include
using namespace std;
int sum = 0;
void print(vector<int> &array) {
cout << '{';
for (int i = 0; i < array.size(); ++i)
cout << array[i] << ' ';
cout << '}' << endl;
}
void swap(vector<int> &arr, int i, int j) {
if (i == j)
return;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
bool isswap(vector<int> &arr, int index) {
for (int i = index + 1; i < arr.size(); ++i) {
if (arr[i] == arr[index])
return false;
}
return true;
}
void permutaion(vector<int> &array, int begin) {
if (begin == array.size() - 1){
++sum;
print(array);
}
for (int i = begin; i < array.size(); ++i) {
if (isswap(array, i)) {
swap(array, i, begin);
permutaion(array, begin + 1);
swap(array, i, begin);
}
}
}
int main() {
vector<int> array{1, 2, 3, 3};
permutaion(array, 0);
cout << "sum = " << sum << endl;
return 0;
}
题目1: 求字符的所有组合(不含重复字符)
例子:
如,输入三个字符a、b、c,则它们的组合有a、b、c、ab、ac、bc、abc.
当交换字符串中的两个字符时,虽然能得到两个不同的排列,但却是同一个组合,比如ab和ba是不同的排列,但只算一个组合。
分析:
代码:
#include
#include
#include
using namespace std;
static int num = 1;
void Combination(char *str, int number, vector<char> &result, vector<string> &results);
vector<string> Combination(char *str)
{
std::vector<string> results;
if (str == nullptr)
return results;
int i, length = strlen(str);
for (i = 1; i <= length; ++i) {
std::vector<char> result;
Combination(str, i, result, results);//在长度为string字符串中取出i个组合数
}
return results;
}
void Combination(char *str, int number, vector<char> &result, vector<string> &results)
{
if (str == nullptr)
return;
if (number == 0)
{
string resultStr = "";
//遍历vector
for (vector<char>::iterator iter = result.begin(); iter != result.end(); ++iter)
{
resultStr += *iter;
}
results.push_back(resultStr);
return;
}
if (*str == '\0')
return;
result.push_back(*str);
Combination(str + 1, number - 1, result, results);
result.pop_back();
Combination(str + 1, number, result, results);
}
题目1-1: 字符串的全组合(包含重复字符)
#pragma warning(disable:4996)
#include
#include
#include
#include
using namespace std;
void Combination(char* begin, char* _string, int number, vector<char>& result, unordered_map<char, int>& map)
{
if (number == 0)
{
vector<char>::iterator iter = result.begin();
for (; iter < result.end(); ++iter)
cout << (*iter);
cout << endl;
return;
}
if (*_string == '\0')
return;
int count1 = 0;
int len = map[*_string];
for (; count1 < len; ++count1)
{
result.push_back(*_string);
Combination(begin, _string + 1, number - 1 - count1, result, map);
}
for (int i = 0; i < count1; ++i)
result.pop_back();
Combination(begin, _string + 1, number, result, map);
}
void Combination(char* _string)
{
unordered_map<char, int>map;
if (_string == NULL)
return;
int len = strlen(_string);
for (int i = 0; i < len; ++i)
{
++map[_string[i]];
}
int index = 0;
for (int i = 0; i < 26; ++i)
{
if (map['a' + i])
{
_string[index++] = 'a' + i;
}
}
_string[index++] = '\0';
vector<char> result;
for (int i = 1; i <= len; i++)
{
Combination(_string, _string, i, result, map);
}
}
int main()
{
char s[] = "abcb";
Combination(s);
system("pause");
return 0;
}
题目2: 正方体8顶点和
输入一个含有8个数字的数组,判断有没有可能把这8个数字分别放到正方体的8个顶点上,使得正方体上三组相对的面上的4个顶点的和相等。
分析:
这相当于先得到a1,a2,a3,a4,a5,a6,a7,a8这8个数字所有的排列,然后判断有没有某一个排列符合题目中给定的条件。
条件为:a1+a2+a3+a4 == a5+a6+a7+a8,a1+a3+a4+a7 == a2+a4+a6+a8,并且 a1+a2+a5+a6 == a3+a4+a7+a8.
题目3: 国际象棋摆皇后
在8*8的国际象棋棋盘上摆放8个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行、同一列或者同一条对角线上。请问有多少种摆法?
分析:
i-j==ColumnIndex[i]-ColumnIndex[j]
或者j-i==ColumnIndex[i]-ColumnIndex[j]
。