反转字符串
描述
写出一个程序,接受一个字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000)
数据范围:数据范围: 0≤n≤10000
要求:空间复杂度 O(n),时间复杂度 O(n)
char* solve(char* str ) { // write code here if (str == NULL) { return NULL; } int len = strlen(str); char *out = malloc(len * (sizeof(char) + 1)); if (out == NULL) { return NULL; } for (int j=0,i = len -1; i >= 0; i--,j++) { out[j] = str[i]; } memcpy(str, out, len); free(out); return str; }
函数目的是原地反转字符串,但存在几个问题:
- 内存分配错误:malloc(len * (sizeof(char) + 1)) 分配了多余的空间(应该是 len + 1 用于 \0)
- 内存泄漏风险:如果 memcpy 前发生错误,out 未被释放
- 未处理字符串终止符:反转后的字符串可能缺少 \0
- 不必要的内存分配:可以直接在原字符串上反转,无需额外空间
优化后的版本:
#include <string.h> #include <stdlib.h> char* solve(char* str) { if (str == NULL) { return NULL; } int len = strlen(str); // strlen → 逻辑长度(不包含 \0) // sizeof → 物理存储大小(包含 \0) for (int i = 0, j = len - 1; i < j; i++, j--) { // 交换字符 char temp = str[i]; str[i] = str[j]; str[j] = temp; } return str; }
- 原地操作:直接在原字符串上交换字符,无需 malloc/free,避免内存泄漏风险。
- 高效交换:使用双指针(头尾指针)向中间遍历,时间复杂度 O(n/2)。
- 正确处理 \0:strlen 已经计算了 \0 之前的位置,反转不影响终止符。