代码随想录算法训练营第八天 | LeeCode 344. 反转字符串, 541. 反转字符串II,卡码网:54.替换数字 ,151.翻转字符串里的单词 ,卡码网:55.右旋转字符串

本文介绍了几种字符串操作的编程题,包括反转整个字符串、每2k字符反转、数字字符替换为number、单词反转以及字符串右旋转。通过示例和代码展示了如何使用双指针、异或运算等技巧在O(1)空间复杂度下解决问题。

 344.反转字符串

题目链接

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

示例 1:
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]

示例 2:
输入:["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]

void reverseString(char* s, int sSize) {
    // 定义左右指针
    int left = 0, right = sSize - 1;
    // 交换左右指针对应的字符,直到左指针大于等于右指针
    while (left < right) {
        // 使用异或运算交换字符
        s[left] ^= s[right];
        s[right] ^= s[left];
        s[left] ^= s[right];
        // 移动指针
        left++;
        right--;
    }
}

541. 反转字符串II

题目链接

给定一个字符串 s 和一个整数 k,从字符串开头算起, 每计数至 2k 个字符,就反转这 2k 个字符中的前 k 个字符。

如果剩余字符少于 k 个,则将剩余字符全部反转。

如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

示例:

输入: s = "abcdefg", k = 2
输出: "bacdfeg"

代码随想录提及思路:

void reverse(char* s, int start, int end) {
    while (start < end) {
        char temp = s[start];
        s[start] = s[end];
        s[end] = temp;
        start++;
        end--;
    }
}

char* reverseStr(char* s, int k) {
    int len = strlen(s);
    for (int i = 0; i < len; i += 2 * k) {
        if (i + k <= len) {
            reverse(s, i, i + k - 1);
        } else {
            reverse(s, i, len - 1);
        }
    }
    return s;
}

替换数字

题目页面

给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。

例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。

对于输入字符串 "a5b",函数应该将其转换为 "anumberb"

输入:一个字符串 s,s 仅包含小写字母和数字字符。

输出:打印一个新的字符串,其中每个数字字符都被替换为了number

样例输入:a1b2c3

样例输出:anumberbnumbercnumber

数据范围:1 <= s.length < 10000

#include<stdio.h>
#include<string.h>

int main() {
	char s[10000];
	while (scanf("%s", s) != EOF) {
		int count = 0;
		int sOldSize = strlen(s);
		for (int i = 0; i < sOldSize; i++) {
			if (s[i] >= '0' && s[i] <= '9') {
				count++;
			}
		}
		int sNewSize = sOldSize + count * 5;
		char newS[sNewSize + 1];
		newS[sNewSize] = '\0'; // 确保新字符串以空字符结尾
		for (int i = sNewSize - 1, j = sOldSize - 1; j >= 0; j--) {
			if (s[j] >= '0' && s[j] <= '9') {
				newS[i] = 'r';
				newS[i - 1] = 'e';
				newS[i - 2] = 'b';
				newS[i - 3] = 'm';
				newS[i - 4] = 'u';
				newS[i - 5] = 'n';
				i -= 5;
			} else {
				newS[i] = s[j];
			}
			i--;
		}
		printf("%s\n", newS);
	}
	return 0;
}

看了很久,理解很多思路,在众多帮助下才理解了代码,

151.翻转字符串里的单词

题目链接

给定一个字符串,逐个翻转字符串中的每个单词。

示例 1:
输入: "the sky is blue"
输出: "blue is sky the"

示例 2:
输入: "  hello world!  "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。

示例 3:
输入: "a good   example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个

思路:

  1. 首先去除字符串两端的空格。
  2. 然后将字符串中的单词按照空格分割出来,并存储到一个数组中。
  3. 对这个数组中的单词进行逆序处理。
  4. 最后将逆序处理后的单词再次连接成一个新的字符串。
// 翻转字符串中指定范围的字符
void reverse(char* s, int start, int end) {
	while (start < end) {
		char tmp = s[start];
		s[start] = s[end];
		s[end] = tmp;
		start++;
		end--;
	}
}

// 删除字符串两端和中间多余的空格
void removeExtraSpace(char* s) {
	int len = strlen(s);
	int start = 0, end = len - 1;
	while (start <= end && s[start] == ' ') start++; // 移除前导空格
	while (start <= end && s[end] == ' ') end--; // 移除尾部空格
	int slow = 0;
	for (int fast = start; fast <= end; fast++) {
		if (s[fast] == ' ' && s[fast - 1] == ' ') continue; // 连续空格
		s[slow++] = s[fast];
	}
	s[slow] = '\0';
}

// 翻转字符串中的单词
char * reverseWords(char * s){
	removeExtraSpace(s);
	reverse(s, 0, strlen(s) - 1);
	int slow = 0;
	for (int i = 0; i <= strlen(s); i++) {
		if (s[i] == ' ' || s[i] == '\0') {
			reverse(s, slow, i - 1);
			slow = i + 1;
		}
	}
	return s;
}

右旋字符串 

题目链接

字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。

例如,对于输入字符串 "abcdefg" 和整数 2,函数应该将其转换为 "fgabcde"。

输入:输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。

输出:输出共一行,为进行了右旋转操作后的字符串。

#include <stdio.h>
#include <string.h>

void rightRotateString(char* s, int k) {
	int len = strlen(s);
	if (len == 0) return; // 字符串为空时直接返回
	k %= len; // 防止 k 的值大于字符串长度,取余确保 k 在一个合理的范围内
	if (k == 0) return; // 如果 k 为 0,表示不需要右旋转,直接返回
	
	// 将后面 k 个字符移到字符串的前面
	char temp[k]; // 临时数组,用于保存后面 k 个字符
	memcpy(temp, s + len - k, k); // 将后面 k 个字符复制到临时数组中
	memmove(s + k, s, len - k); // 将前面 len - k 个字符向右移动 k 个位置
	memcpy(s, temp, k); // 将临时数组中的字符复制到字符串的开头
}

int main() {
	int k;
	char s[1000]; // 假设输入的字符串不超过 1000 个字符
	
	// 输入需要右旋转的位数和字符串
	scanf("%d", &k);
	scanf("%s", s);
	
	// 对字符串进行右旋转操作
	rightRotateString(s, k);
	
	// 输出右旋转后的字符串
	printf("%s\n", s);
	
	return 0;
}

总结:今天的题目依旧稳定发挥,做了很久,反转反转反转,快麻木了,很多代码写不出来,查了很多资料,问了别人,问了ai找问题,当然双指针方法还是得加紧巩固,只能说继续加油吧。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值