这是我参与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);
}
啊这,运行速度才击败了8%?占用内存才击败了32%?
我自己跳进去🗑
再试
target[end]=from[i];
这一段代码用到的i
和end
,前者是增,后者是减。
那这里做的事情不就是:把头放到尾,然后又把尾放到头,这时候的时间复杂度就是O(n),用一个 for 循环来做交换首尾的事情不划算啊。
我们直接交换首尾就好了,使用两个指针,一个指向头(l),一个指向尾(r),前者往后移,后者往前移,每趟循环就交换两个指针指向的数据
,还省去了创建一个char
数组。
还要看一下两个指针相交的情况:
- 字符串为奇数,
1,2,3
,一开始,l 指向 1,r 指向 3,l(0),r(2)
,交换之后,l(1),r(1)
,当 l 等于 r 时停止。 - 字符串为偶数,
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);
}
乏了。
果然牛客的算法排名就是个摆设,我也前面也说了。
目前的
String
类几乎没有功能能够“一键”完成这个功能
然而我看到第一名都是使用StringBUilder.reverse()
来实现的,reverse的实现是这样的:
跟我第二次尝试的实现几乎一模一样。
于是我在牛客使用StringBUilder.reverse()
跑了一下。
总结
牛客的结果就看看而已(每次跑都差别很大),好好锻炼自己的思维才是最重要的!
今日算法,结束。
这里是程序员徐小白,【每日算法】是我新开的一个专栏,在这里主要记录我学习算法的日常,也希望我能够坚持每日学习算法,不知道这样的文章风格您是否喜欢,喜欢的不妨点个赞,您的点赞、收藏以及评论都是我下班后坚持更文的动力。