目录
题目:输入一个字符串,按字典序打印出该字符串中字符的所有排列。
题目:输入一个含有8个数字的数组,把这8个数字放在正方体的8个顶点上,使得正方体上相对的面上的4个顶点的和都相等。
题目:在一个字符串中找到第一个只出现一次的字符,并返回它的位置。
题目:定义一个函数,输入两个字符串,从第一个字符串中删除在第二个字符串中出现的所有字符。
题目:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba.
看下图,用回溯法,直观明了。
图片来自牛客网剑指offer中一位网友的回答。
/*
这是一个字符串排列问题,考虑使用回溯法
可以分为两部分来做
第一部分:求所有可能在第一个位置的字符,即把第一个字符与后面所有字符交换,包括自己和自己交换
第二部分:固定第一个字符,求后面所有字符的排列,即又回到第一部分
其中注意一个问题:如果第一个字符与后面某一个位置字符相同,则不用交换
*/
class Solution {
public:
vector<string> Permutation(string str) {
vector<string> all;
if(str.size() == 0){
return all;
}
string tmp;
recur(str, tmp, all, 0);
return all;
}
void recur(string str, string& tmp, vector<string> &all, int start){
if(start < 0 || str.size() == 0){
return;
}
if(str.size() == start){
all.push_back(tmp);
return;
}
for(int i = start; i < str.size(); i++){
if(i != start && str[i] == str[start]){ //如果字符相同,不用交换
continue;
}
swap(str[i], str[start]);
tmp += str[start];
recur(str, tmp, all, start + 1);
tmp.pop_back(); //回溯法的关键
}
}
};
题目:输入一个字符串,求字符的所有组合。例如:输入abc,则它们的组合有a、b、c、ab、ac、bc、abc。其中ab和ba只是一种组合。
/*
输入n个字符,那么形成的组合长度有1、2、... 、n
在n个字符中求长m的字符时,可以分成两部分:第一个字符和其余所有字符
如果组合中包含第一个字符,则在剩余字符中求m-1个字符
如果组合中不包含第一个字符,则在剩余字符中求m个字符
就可以用递归的方法求解
*/
class Solution
{
public:
vector<string> combination(string str){
vector<string> all;
if (str.size() == 0) {
return all;
}
string tmp;
for (int i = 1; i <= str.size(); i++) {
recur(str, tmp, 0, i, all);
}
return all;
}
void recur(string str, string &tmp, int start, int number, vector<string>& all){
if (number == 0) {
all.push_back(tmp);
return;
}
if (start == str.size()) {
return;
}
if (number > str.size() - start) {
return;
}
tmp += str[start];
recur(str, tmp, start + 1, number - 1, all);
tmp.pop_back();
recur(str, tmp, start + 1, number, all);
}
};
题目:输入一个含有8个数字的数组,判断有没有可能把这8个数字分别放在正方体的8个顶点上,使得正方体上三组相对的面上的4个顶点的和都相等。
/*
简而言之,这就是一个全排列问题
把这8个数全排列,之后判断正方体的三个像对面是否相等即可
*/
class Solutin{
public:
bool cubeVertex(vector<int> vec) {
if (vec.size() != 8) {
r