【每日算法】牛客-NC103 反转字符串

445 阅读1分钟

这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

描述

写出一个程序,接受一个字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000)

数据范围: 0 < n < 1000

要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)

考察过的公司:腾讯百度微盟

做题

虽然这道题目非常简单,但是也有不少大公司考察了,所以不要好高骛远,脚踏实地地做好每一道题非常的重要。

反转字符串,目前的String类几乎没有功能能够“一键”完成这个功能,所以就必须得自己写算法了,不能抄捷径了。

反转字符串,字符串其实也可以转成一个数组的,那么我们就可以使用反转数字的方式来反转字符串。

初试

我的第一个想法是:在创建一个数组,一个数组从尾开始遍历,然后按从头开始的顺序把数据插入到另外一个数组。

于是我写了以下的代码:

public String solve (String str) {
        // write code here
        char[] target = new char[str.length()];
        char[] from = str.toCharArray();
        int end=str.length()-1;
        for(int i=0;i<str.length();i++){
            target[end]=from[i];
            end--;
        }
        return new String(target);
    }

image.png

啊这,运行速度才击败了8%?占用内存才击败了32%?

我自己跳进去🗑

再试

target[end]=from[i];这一段代码用到的iend,前者是增,后者是减。

那这里做的事情不就是:把头放到尾,然后又把尾放到头,这时候的时间复杂度就是O(n),用一个 for 循环来做交换首尾的事情不划算啊。

我们直接交换首尾就好了,使用两个指针,一个指向头(l),一个指向尾(r),前者往后移,后者往前移,每趟循环就交换两个指针指向的数据 ,还省去了创建一个char数组。

还要看一下两个指针相交的情况:

  1. 字符串为奇数,1,2,3,一开始,l 指向 1,r 指向 3,l(0),r(2),交换之后,l(1),r(1),当 l 等于 r 时停止。
  2. 字符串为偶数,1,2,3,4,一开始,l 指向 1,r 指向 4,l(0),r(3),交换一次后,l(1),r(2),l 指向 2,r 指向 3,再交换一次,l(2),r(1),当 l 大于 r 时停止。

以上两种情况合并,我们得到了当循环停止时所满足的条件:l >= r,那我们循环的条件就是 l < r。

public String solve (String str) {
        // write code here
        char[] from = str.toCharArray();
        int r=str.length()-1;
        char temp=' ';
        for(int l=0;l<r;l++){
            temp=from[r];
            from[r--]=from[l];
            from[l]=temp;
        }
        return new String(from);
    }

image.png

乏了。

果然牛客的算法排名就是个摆设,我也前面也说了。

目前的String类几乎没有功能能够“一键”完成这个功能

然而我看到第一名都是使用StringBUilder.reverse()来实现的,reverse的实现是这样的:

image.png

跟我第二次尝试的实现几乎一模一样。

于是我在牛客使用StringBUilder.reverse()跑了一下。

image.png

总结

牛客的结果就看看而已(每次跑都差别很大),好好锻炼自己的思维才是最重要的!

今日算法,结束。

这里是程序员徐小白,【每日算法】是我新开的一个专栏,在这里主要记录我学习算法的日常,也希望我能够坚持每日学习算法,不知道这样的文章风格您是否喜欢,喜欢的不妨点个赞,您的点赞、收藏以及评论都是我下班后坚持更文的动力。