代码随想录算法训练营第七天|LeetCode 334.反转字符串、541反转字符串II、151反转字符串中的单词

一、LeetCode 334.反转字符串

题目链接:. - 力扣(LeetCode)

题目描述:编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

 题目思路:

        与反转链表相同,依旧采用的是双指针的方法,只不过相对于链表,字符串的反转更为简单一点,因为字符串是数组,所以元素在内存中是连续分布的,这就决定了两者反转的差异。

        定义两个指针,分别指向字符串的首端和末尾端,然后交换两个指针所指的内容,然后两个指针靠近,直到两个指针的位置重叠即退出。

void reverseString(char* s, int sSize) {
     int left=0;//左指针
     int right=sSize-1;//右指针
     while(left<right)//两个指针位置不重叠就交换
     {
        char c=s[left];
        s[left++]=s[right];
        s[right--]=c;
     }
}

二、LeetCode 541.反转字符串II

题目描述:

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

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

题目思路: 

与上题的做法基本一致,只不过加了一些限定条件,看似有三个限制条件,其实在书写代码的时候,只需要判断其剩余字符是不是大于K,如果大于做法都是一样的,因为不管剩余字符剩余多少都不会进行翻转。如果小于,急需要调整一下翻转的范围。

char* reverseStr(char* s, int k) {
    int len=strlen(s);//取出整体长度
    for(int i=0;i<len;i+=(2*k))//判断翻转还能不能进行
    {
        k=i+k>len?len-i:k;//判断剩余的长度,决定右指针的位置
        int left=i;
        int right=i+k-1;
        while(left<right)//两两交换
        {
           char c=s[left];
           s[left++]=s[right];
           s[right--]=c;
        }
    }
    return s;
}

三、LeetCode 151.反转字符串的单词

题目描述:

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

题目思路:

        本题相对于前面两个题目稍微复杂一点,但是本质是一样的,具体做法是,首先我们要先将字符串中多余的空格进行去除,哪些呢?首端的空格,尾端的空格,以及字符串中两个单词的连续空格,采用什么样的的做法呢?采用双指针(快慢指针的方式),然后将所有的字符串进行反转,然后将对应单词进行翻转。 

void remov_k(char* s)//去除空格函数
{
  int start=0;
  int end=strlen(s)-1;
  while(s[start]==' ')//去除前端空格
    start++;
  while(s[end]==' ')//去除后端空格
    end--;
    int slow=0;
    for(int i=start;i<=end;i++)//利用快慢指针去除内部空格
    {
        if(s[i]==' ' && s[i+1]==' ')
        {
            continue;
        }
        s[slow]=s[i];
        slow++;
    }
    s[slow]='\0';
}

void reverse(char *s,int start,int end)//字符串反转,这个函数可以长字符串反转,也可短字符串进行反转
{
   int i=start;
   int j=end;
    while(i<j)
    {
        int tmp=s[i];
        s[i++]=s[j];
        s[j--]=tmp;
    }
}

char* reverseWords(char* s) {
    remov_k(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;
}

 四、KamaCoder 55.优选字符串

题目链接:55. 右旋字符串(第八期模拟笔试)

题目描述:

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

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

题目思路:与上面的题目一致,先进行大部分字符的反转,在进行局部的反转。

 

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

void reverse(char* s,int left,int right)//子符串交换函数
{
    while(left<right)
    {
        char c=s[left];
        s[left++]=s[right];
        s[right--]=c;
    }
}    
    void rightRotate(char *s,int k)
    {
        int len=strlen(s);
        reverse( s,0,len-1);   
        reverse( s,0,k-1); 
        reverse( s,k,len-1); 
    }
    int main()
    {
        int k;
        scanf("%d",&k);
        char s[10000];
        scanf("%s",s);
       rightRotate(s,k);
       printf("%s\n",s);
        
    }
    

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值