目录
引言
这道题十分经典,是大厂的面试题,第一种思路比较容易想到,但是时间复杂度比较高,第二种思路相对第一种时间复杂度就少了很多。本篇文章将一个复杂的问题简单化,一步步深入学习,最终编写出了一个实用性强的函数。
题目再现
char arr[100]=“I am a student”,将"I am a student"中的空格替换成2个’#',使其成为I##am##a##student
分析
思路一
算法设计
- 定义i ,从0下标开始,向后遍历
- 若不是要替换的字符,i++,继续向后遍历
- 若是要替换的字符
- 将当前位置后序数据向后移动
- arr[i++]=’#’;arr[i++]=’#’;
编程实现
//时间复杂度O(n^2) 空间:O(1)
void replace1(char* arr) {
int len = strlen(arr);
int count = 0;
for (int i = 0; i < len+count; i++) {
if (arr[i] == ' ') {
count++;
//数据移动
for (int j = len + i; j > i; j--) {
arr[j+1] = arr[j];
}
arr[i] = '#'; i++;
arr[i] = '#';
}
}
}
算法分析
当空格个数为0,访问元素个数为n,空格个数为1,访问元素个数为2n,……空格个数为n,访问元素个数为你nn,平均访问元素个数为n2+n,所以时间复杂度为 O(n^2),空间复杂度为O(1)
思路二
图示理解
变量j的位置根空格的个数有关,即j=i+空格个数(待替换字符个数-1)
算法设计
- i=len,j=i+3;从后向前遍历每一个字符
- 不等于空格,往后赋值,i–,j–
- 等于空格,a[j]=‘#’,j–,a[j]=‘#’,j–,i–
编程实现
//获得目标字符的个数
int getcharcount(char* arr, int len, char aim) {
int count = 0;
for (int i = 0; i < len; i++) {
if (arr[i] == aim) {
count++;
}
}
return count;
}
void replace2(char* arr) {
int len = strlen(arr);
int count = getcharcount(arr,len ,' ');
int i = len, j = len + count;
while (i < j) { //i>=0
if (arr[i] != ' ') {
arr[j--] = arr[i--];
}
else {
arr[j--] = '#';
arr[j--] = '#';
i--;
}
}
}
算法分析
变量i访问了n个元素,变量j也访问了n个元素,一共访问了2n个元素,所以时间复杂度是O(n),空间复杂度就是O(1)
程序测试(第二种为例)
int getcharcount(char* arr, int len, char aim) {
int count = 0;
for (int i = 0; i < len; i++) {
if (arr[i] == aim) {
count++;
}
}
return count;
}
时间复杂度O(n) 空间:O(1)
void replace2(char* arr) {
int len = strlen(arr);
int count = getcharcount(arr,len ,' ');
int i = len, j = len + count;
while (i < j) { //i>=0
if (arr[i] != ' ') {
arr[j--] = arr[i--];
}
else {
arr[j--] = '#';
arr[j--] = '#';
i--;
}
}
}
int main() {
char arr[SIZE] = "i am a student";
//char brr[] = "##%";
//replace4(arr, ' ', brr);
//replace3(arr, 't', 4, '*');
//replace3(arr, ' ', 2, '#');
replace2(arr);
printf("%s\n", arr);
return 0;
}
运行的结果如下
封装函数
任意一个字符替换成任意个数的相同字符
void replace3(char* arr,char src,int n,char aim) {
int len = strlen(arr);
int count = getcharcount(arr, len, src); //arr中src字符出现次数,前面已经实现
int i = len, j = len + (n-1)*count;//count就是src的个数
while (i < j) { //i>=0
if (arr[i] != src) {
arr[j--] = arr[i--];
}
else {
for (int z = 0; z < n; z++) {
arr[j--] = aim;
}
i--;
}
}
}
任意一个字符替换成任意个数的字符串
void replace4(char* arr, char src, char* brr) {
int len = strlen(arr);
int n = strlen(brr);
int count = getcharcount(arr, len, src); //arr中src字符出现次数
int i = len, j = len + (n - 1) * count;
while (i < j) { //i>=0
if (arr[i] != src) {
arr[j--] = arr[i--];
}
else {
for (int z = n - 1; z >= 0; z--) {
arr[j--] = brr[z];
}
i--;
}
}
}
程序测试2
void replace4(char* arr, char src, char* brr) {
int len = strlen(arr);
int n = strlen(brr);
int count = getcharcount(arr, len, src); //arr中src字符出现次数
int i = len, j = len + (n - 1) * count;
while (i < j) { //i>=0
if (arr[i] != src) {
arr[j--] = arr[i--];
}
else {
for (int z = n - 1; z >= 0; z--) {
arr[j--] = brr[z];
}
i--;
}
}
}
//SIZE=100
int main() {
char arr[SIZE] = "i am a student";
char brr[] = "%20";
replace4(arr, ' ', brr);
printf("%s\n", arr);
return 0;
}
运行的结果如下