力扣 反转字符串 II

题目分析:

1.根据题目要求,每次需要反转前 K 个字符;

2.结束时需要判断剩余字符个数是否大于 K 个,若大于 K 则反转前 K 个字符,若小于 K 则反转剩余的所有字符

3.根据题目要求,我们需要不断地反转字符串,进行重复的操作,所以首先想到使用循环解决问题

4.先进行一次字符串反转,再推到整个循环的开始结束条件.

5.由于需要进行字符串反转,而且是在字符串内部进行反转,所以需要反转的位置,从哪里开始,从哪里结束。因此,使用到双指针的思想

具体实现

1.定义两个变量,分别存储反转字符串的左右下标

int l = 0;  //指向当前位置
int r = 0;  //要交换的位置
int len = s.length();

2.开始进入字符串反转条件判断      

  (1)当剩余字符少于 K 个时,也就是当 len - 1 - i < k  的时候,这个时候剩余的字符数量小于 K ,需要反转剩下的字符串。

                用 l 保存反转的起始位置,用 r 保存反转的结束位置

                使用 while 循环反转这段字符串

//剩余字符少于k个,反转剩下的链表
if (len - 1 - i < k)
{
    l = i;
    r = len - 1;

    //反转
    while (l < r)
    {
        char t = s[l];
        s[l] = s[r];
        s[r] = t;
        l++;
        r--;
    }

}

        (2)当剩余字符大于 K 个,并且小于 2K 个时,也就是len-1-i<2k 时。需要反转前 K 个字符。

                此时的 if 条件为 else if 通过上面的 if 条件已经过滤了 len - 1 - i < k 的情况,所以只需要判断此时剩余的字符数量是否小于 2*K

                设置 交换位置的起始和终止下标,进入交换

else if(len-1-i<2k)
{
    l = i;
    r = i + k - 1;


    while (l < r)
    {
        char t = s[l];
        s[l] = s[r];
        s[r] = t;
        l++;
        r--;
    }
}

        (3)当不属于前面两种条件时,只剩下一种条件了,即 len -1 -i >=2K 此时,字符串还可以继续进行反转,字符串未结束

else if(len-1-i<2k)
{
    l = i;
    r = i + k - 1;


    while (l < r)
    {
        char t = s[l];
        s[l] = s[r];
        s[r] = t;
        l++;
        r--;
    }
}

3.编写 for 循环包含字符串反转操作。

        (1)当写完前面三段代码时,可以很清楚的感受到代码十分冗余,特别是 while 循环的部分一模一样的代码使用了三次。

        (2)优化代码结构,将三段代码的while循环放在 if -else if-else 语句之后,if 语句就只需要考虑反转条件判断和反转位置设置了。

        (3)当我们将while 循环的位置优化之后,可以发现,条件len-1-i<2k 和 条件len -1 -i >=2K的 if 语句中的反转下标位置设置是一样的,那么为什么不将 else if-else语句合并成一条语句呢。

        

for (int i = 0; i < len;)
{
    //剩余字符少于k个,反转剩下的链表
    if (len - 1 - i < k)
    {
        l = i;
        r = len - 1;
    }
    //剩余字符大于k个
    else
    {
        l = i;
        r = i + k - 1;
    }
    while (l < r)
    {
        char t = s[l];
        s[l] = s[r];
        s[r] = t;
        l++;
        r--;
    }
    i = i + 2 * k;
}

4.优化代码结构之后,代码利用效率就大大提高了,而且,我们可以使用 i < len 进行结束条件判断,字符串不管如何进行交换,如果没有到达末尾,字符串就会继续进行交换,如果到达了末尾,条件 i = i + 2 * k; 也会让for 循环跳出。一举两得。

完整代码

class Solution {
public:
    string reverseStr(string s, int k)
    {
        int l = 0;  //指向当前位置
        int r = l + k - 1;  //要交换的位置
        int len = s.length();
        for (int i = 0; i < len;)
        {
            //剩余字符少于k个,反转剩下的链表
            if (len - 1 - i < k)
            {
                l = i;
                r = len - 1;
            }
            //剩余字符大于k个
            else
            {
                l = i;
                r = i + k - 1;
            }
            while (l < r)
            {
                char t = s[l];
                s[l] = s[r];
                s[r] = t;
                l++;
                r--;
            }
            i = i + 2 * k;
        }
        return s;
    }
};

提交结果

  • 17
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值