请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
最简单的方法就是从头到尾遍历,但是时间复杂度为O(n^2)。
本文采用一种时间复杂度为O(n)的方法。
我们可以先遍历一次字符串,这样就可以统计出字符串空格的总数,并可以由此计算出替换之后的字符串的总长度。每替换一个空格,长度增加2,因此替换以后字符串的长度等于原来的长度加上2乘以空格数目。以"We are happy"为例,"We are happy"这个字符串的长度为14(包括结尾符号"\n"),里面有两个空格,因此替换之后字符串的长度是18。
我们从字符串的尾部开始复制和替换。首先准备两个指针,P1和P2,P1指向原始字符串的末尾,而P2指向替换之后的字符串的末尾。接下来我们向前移动指针P1,逐个把它指向的字符复制到P2指向的位置,直到碰到第一个空格为止。碰到第一个空格之后,把P1向前移动1格,在P2之前插入字符串"%20"。由于"%20"的长度为3,同时也要把P2向前移动3格。
移动示意图:
C++:
class Solution {
public:
void replaceSpace(char *str,int length) {
if(str == NULL || length <= 0){
return;
}
/*original_length为字符串str的实际长度*/
int original_length = 0; //原始长度
int number_blank = 0; //空格数
int i;
while(str[i++] != '\0'){ //遍历字符串
++original_length; //长度+1
if(str[i] == ' '){
++number_blank; //遇到空格+1
}
}
/*new_length为把空格替换成'%20'之后的长度*/
int new_length = original_length + 2 * number_blank;
int index_original = original_length-1; //原始字符串末尾索引值
int index_new = new_length-1; //计算长度后的字符串末尾索引值
/*index_original指针开始向前移动,如果遇到空格,替换成'%20',否则进行复制操作*/
while(index_original >= 0 && index_new > index_original){
if(str[index_original] == ' '){
str[index_new--] = '0';
str[index_new--] = '2';
str[index_new--] = '%';
}
else{
str[index_new--] = str[index_original];
}
--index_original;
}
}
};
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
我们求整个字符串的排列,可以看成两步:首先求所有可能出现在第一个位置的字符,即把第一个字符和后面所有的字符交换。如下图所示:
上图就是分别把第一个字符a和后面的b、c等字符交换的情形。首先固定第一个字符,求后面所有字符的排列。这个时候我们仍把后面的所有字符分为两部分:后面的字符的第一个字符,以及这个字符之后的所有字符。然后把第一个字符逐一和它后面的字符交换。
这个思路,是典型的递归思路。
C++:
class Solution {
public:
vector Permutation(string str) {
//判断输入
if(str.length() == 0){
return result;
}
PermutationCore(str, 0);
//对结果进行排序
sort(result.begin(), result.end());
return result;
}
private:
void PermutationCore(string str, int begin){
//递归结束的条件:第一位和最后一位交换完成
if(begin == str.length()){
result.push_back(str);
return;
}
for(int i = begin; i < str.length(); i++){
//如果字符串相同,则不交换
if(i != begin && str[i] == str[begin]){
continue;
}
//位置交换
swap(str[begin], str[i]);
//递归调用,前面begin+1的位置不变,后面的字符串全排列
PermutationCore(str, begin + 1);
}
}
vector result;
};
在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置。
建立一个哈希表,第一次扫描的时候,统计每个字符的出现次数。第二次扫描的时候,如果该字符出现的次数为1,则返回这个字符的位置。
C++:
class Solution {
public:
int FirstNotRepeatingChar(string str) {
int length = str.size();
if(length == 0){
return -1;
}
map item;
for(int i = 0; i < length; i++){
item[str[i]]++;
}
for(int i = 0; i < length; i++){
if(item[str[i]] == 1){
return i;
}
}
return -1;
}
};
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
观察字符串变化规律,你会发现这道题很简单。只需要对每个单词做翻转,然后再整体做翻转就得到了正确的结果。
C++:
class Solution {
public:
string ReverseSentence(string str) {
string result = str;
int length = result.size();
if(length == 0){
return "";
}
// 追加一个空格,作为反转标志位
result += ' ';
int mark = 0;
// 根据空格,反转所有单词
for(int i = 0; i < length + 1; i++){
if(result[i] == ' '){
Reverse(result, mark, i - 1);
mark = i + 1;
}
}
// 去掉添加的空格
result = result.substr(0, length);
// 整体反转
Reverse(result, 0, length - 1);
return result;
}
private:
void Reverse(string &str, int begin, int end){
while(begin < end){
swap(str[begin++], str[end--]);
}
}
};
稍微改动一下
class Solution {
public:
string ReverseSentence(string str) {
string result=str;
int length = result.size();
if(length<=0){
return "";
}
int mark = 0;
Reverse(result,0,length-1);
for(int i=0;i
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!?
例如:输入字符串"abcdefg"和数字2,该函数将返回左旋转2位得到的结果"cdefgab";
第一步:翻转字符串“ab”,得到"ba";
第二步:翻转字符串"cdefg",得到"gfedc";
第三步:翻转字符串"bagfedc",得到"cdefgab";
或者:
第一步:翻转整个字符串"abcdefg",得到"gfedcba"
第二步:翻转字符串“gfedc”,得到"cdefg"
第三步:翻转字符串"ba",得到"ab"
C++:
class Solution {
public:
string LeftRotateString(string str, int n) {
string result = str;
int length = result.size();
if(length < 0){
return NULL;
}
if(0 <= n <= length){
int pFirstBegin = 0, pFirstEnd = n - 1;
int pSecondBegin = n, pSecondEnd = length - 1;
ReverseString(result, pFirstBegin, pFirstEnd);
ReverseString(result, pSecondBegin, pSecondEnd);
ReverseString(result, pFirstBegin, pSecondEnd);
}
return result;
}
private:
void ReverseString(string &str, int begin, int end){
while(begin < end){
swap(str[begin++], str[end--]);
}
}
};
答案来自 :https://blog.csdn.net/c406495762/article/details/79247243