打卡 DAY 26 反转字符串中的单词

力扣原题链接

一、题目描述

二、思路

先删去多余空格,再反转整个字符串,最后反转各个单词。

e.g.

删去多余空格:用双指针法,类似于 打卡 DAY 2 数组:移除元素 。

三、解题过程

  • 实现字符串反转接口函数

  • 利用双指针从字符串的左右分别开始遍历,交换左右指针所指元素:
void charSwap(char* arr, int left, int right){
    while(left < right){
        char tmp = arr[left];
        arr[left++] = arr[right];
        arr[right--] = tmp;
    }
}
  • 删去多余空格

  • 先初始化左右指针,然后开始遍历数组。

  • 当字符串第一位为空格(s [ right ] == ' ' && right == 0)或 right 指针所指元素为空格且 right 指针前一位元素也是空格时(s [ right ] == ' ' && s [ right - 1 ] == ' '),将 right 指针往后移向所指元素不为空格处,(注意!!当最后两位及以上元素都为空格时,right 会被移向 '\0' 的位置,即 right == len,此时需将 right-- ,否则 left 所指元素不会被赋空格,以至于后面无法判断结果数组结尾及长度

  • 然后对左指针所指元素赋予右指针所指元素的值。注意!!跳出循环后的 left 是结果数组的长度!!

  • 随后如果结果数组长度小于原数组长度,则对结果数组的 left 位置赋上终止符 '\0':

    //先删去多余空格
    int len = strlen(s);
    int left = 0, right = 0;
    for(; right < len; right++, left++){
        if(s[right] == ' ' && (right == 0 || s[right - 1] == ' ')){
            while(right < len && s[right] == ' ') right++;
            if(right == len) right --;
        }
        s[left] = s[right];
    }
    while(s[left - 1] == ' ') left--;
    if(left < len) s[left] = '\0';
    int newLen = left;
  • 反转整个字符串

    //反转整个字符串
    charSwap(s, 0, newLen - 1);
  • 分别反转各个单词

    //将各个单词反转
    for(left = 0, right = 0; right < newLen; right++){
        if(s[right] == ' '){
            charSwap(s, left, right - 1);
            left = right + 1;
        }
        else if(right == newLen - 1) charSwap(s, left, right);
    }
  • 返回结果数组

    return s;

四、代码

void charSwap(char* arr, int left, int right){
    while(left < right){
        char tmp = arr[left];
        arr[left++] = arr[right];
        arr[right--] = tmp;
    }
}

char * reverseWords(char * s){
    int len = strlen(s);
    int left = 0, right = 0;
    for(; right < len; right++, left++){
        if(s[right] == ' ' && (right == 0 || s[right - 1] == ' ')){
            while(right < len && s[right] == ' ') right++;
            if(right == len) right --;
        }
        s[left] = s[right];
    }
    while(s[left - 1] == ' ') left--;
    if(left < len) s[left] = '\0';
    int newLen = left;

    charSwap(s, 0, newLen - 1);

    for(left = 0, right = 0; right < newLen; right++){
        if(s[right] == ' '){
            charSwap(s, left, right - 1);
            left = right + 1;
        }
        else if(right == newLen - 1) charSwap(s, left, right);
    }
    return s;
}

时间复杂度:O(n),空间复杂度:O(1)。

五、遇到的问题

  • 一开始没想到不申请新数组的法子,原本想着是在原数组里用双指针和申请一个长度为删去原数组多余空格后的长度的新数组。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值