力扣541. 反转字符串 II

class Solution {
public:
    void reverse_k(string& s, int start, int end) {
        for(int i = start, j = --end; i < j; i++, j--) {
            char tmp = s[i];
            s[i] = s[j];
            s[j] = tmp;
        }
    }

    string reverseStr(string s, int k) {
        for(int i = 0; i < s.size(); i += 2 * k) {
            if(i + k <= s.size()) {
                reverse_k(s, i, i + k);
            } else {
                reverse_k(s, i, s.size());
            }
        }
        return s;
    }
};
<think>好的,用户问的是C语言在力扣刷题时常见的字符串操作有哪些,以及如何实现。首先,我需要回忆一下常见的字符串题目类型,比如反转字符串、回文检查、字符串转换、子串查找等。然后,针对每个类型,我需要给出对应的实现方法,可能还需要注意C语言的特性,比如字符串以'\0'结尾,使用字符数组等。 用户可能是在准备面试或者刷题,所以需要简洁明了的总结,以及示例代码。同时,用户可能希望了解不同操作的时间复杂度和注意事项,比如内存管理、指针使用是否正确等。此外,用户可能还希望知道一些常见错误,比如越界访问、忘记分配内存等。 接下来,我需要分点列出常见的字符串操作,每个操作给出简要说明和示例代码。例如,反转字符串可以用双指针,回文检查也是类似。字符串转换可能涉及库函数如atoi,或者手动实现。子串查找可以用滑动窗口或者KMP算法。还要注意动态内存分配,比如使用malloc和free,避免内存泄漏。 另外,用户之前的问题是关于内存错误的,所以在回答这个问题时,可能需要强调在C语言中处理字符串时常见的错误点,比如未分配足够的内存、忘记添加结束符'\0'等。同时,给出一些相关问题作为扩展,帮助用户进一步练习。 需要确保示例代码正确,比如反转字符串的函数参数是否正确传递,是否有越界的风险。例如,反转字符串时,交换两个字符,中间变量的使用是否正确,指针移动是否正确。 可能还需要提到一些力扣相关的技巧,比如如何处理输入输出,如何优化时间复杂度等。例如,使用哈希表来处理字符频率统计,或者双指针技巧处理子串问题。 最后,整理出相关问题,帮助用户巩固每个知识点。比如,如何判断两个字符串是否为异位词,如何实现字符串的左旋操作等。 </think>在C语言刷题中,字符串操作是高频考点,常见操作及实现如下: --- ### 1. **字符串反转** ```c void reverseString(char* s, int sSize) { int left = 0, right = sSize - 1; while (left < right) { char tmp = s[left]; s[left] = s[right]; s[right] = tmp; left++; right--; } } ``` **注意**:输入参数是字符数组和长度,需交换字符直到中间位置。 --- ### 2. **判断回文字符串** ```c bool isPalindrome(char* s, int len) { int left = 0, right = len - 1; while (left < right) { if (s[left++] != s[right--]) return false; } return true; } ``` **注意**:忽略非字母数字字符时需先过滤(如力扣125题)。 --- ### 3. **字符串转整数(atoi)** ```c int myAtoi(char* str) { int i = 0, sign = 1, result = 0; // 跳过空格 while (str[i] == ' ') i++; // 处理符号 if (str[i] == '-' || str[i] == '+') { sign = (str[i++] == '-') ? -1 : 1; } // 转换数字 while (isdigit(str[i])) { int digit = str[i++] - '0'; // 溢出处理 if (result > INT_MAX / 10 || (result == INT_MAX / 10 && digit > INT_MAX % 10)) { return (sign == 1) ? INT_MAX : INT_MIN; } result = result * 10 + digit; } return result * sign; } ``` **注意**:需处理前导空格、符号、溢出边界条件。 --- ### 4. **查找最长公共前缀** ```c char* longestCommonPrefix(char** strs, int strsSize) { if (strsSize == 0) return ""; char* prefix = strs[0]; for (int i = 1; i < strsSize; i++) { int j = 0; while (prefix[j] && strs[i][j] && prefix[j] == strs[i][j]) j++; prefix[j] = '\0'; if (j == 0) break; } return prefix; } ``` **注意**:逐个字符比较,逐步缩短公共前缀。 --- ### 5. **子串查找(KMP算法)** ```c // 构建部分匹配表(LPS数组) void computeLPS(char* pattern, int* lps) { int len = 0, i = 1; lps[0] = 0; while (i < strlen(pattern)) { if (pattern[i] == pattern[len]) { len++; lps[i++] = len; } else { if (len != 0) len = lps[len - 1]; else lps[i++] = 0; } } } // KMP主函数 int kmpSearch(char* text, char* pattern) { int M = strlen(pattern), N = strlen(text); int lps[M]; computeLPS(pattern, lps); int i = 0, j = 0; while (i < N) { if (pattern[j] == text[i]) { i++; j++; } if (j == M) return i - j; // 找到匹配 else if (i < N && pattern[j] != text[i]) { if (j != 0) j = lps[j - 1]; else i++; } } return -1; // 未找到 } ``` **注意**:KMP算法时间复杂度O(N+M),优于暴力解法O(N*M)。 --- ### 6. **字符串分割(strtok模拟)** ```c char** splitString(char* str, char* delimiters, int* returnSize) { char* token = strtok(str, delimiters); char** result = (char**)malloc(100 * sizeof(char*)); int idx = 0; while (token != NULL) { result[idx++] = strdup(token); // 复制子串 token = strtok(NULL, delimiters); } *returnSize = idx; return result; } ``` **注意**:`strtok`会修改原字符串,需用`strdup`保存子串。 --- ### 常见错误与优化 1. **内存泄漏**:手动分配内存后需及时释放(如`strdup`返回的指针)。 2. **越界访问**:检查字符串长度(如`strlen`不包含`\0`)。 3. **忽略大小写**:比较时需统一转换(如`tolower`函数)。 4. **暴力解法优化**:滑动窗口(如力扣3题最长无重复子串)。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值