简介
这是一个Java面试中被经常问及的问题,也有很多种实现方式。我在这里一一列出,如果你有更好的解法,也可留言。
解法一:首尾字符调换顺序
由于String对象是只读类型,不能对其进行直接操作,因此需要转换成字符数组,然后调换字符数组中的各个字符。
public String reverse(String str) {
//异常情况处理
if (str == null || str.length() <= 1) {
return str;
}
//调换首尾字符
char[] array = str.toCharArray();
int len = str.length();
for (int i = 0; i < len/2; i++) {
char temp = array[i];
array[i] = array[len - 1 - i];
array[len - 1 - i] = temp;
}
//产生新字符串
return new String(array);
}
这个算法实现需要注意的时,遍历时,到达中间节点遍历结束;如果操作遍历到尾部,相当于将字符串首尾调换后,又调换回原来的状态。
解法二:递归实现
递归算法的话可以每次将字符串首部字符追置换到尾部,并拼接成新的字符串;当字符串里仅有一个字符存在时,结束递归调用。
public String reverse(String str) {
//异常情况处理
if (str == null || str.length() <= 1) {
return str;
}
//递归实现
return reverse(str.substring(1)) + str.charAt(0);
}
解法三:使用StringBuffer的reverse()函数
借助StringBuffer/StringBuilder的reverse()函数,可以实现字符串的反转,但需要在StringBuffer/StringBuilder和String类型之间进行转换。这里需要注意一下StringBuffer和StringBuilder的差异:StringBuffer是线程安全的,StringBuilder是非线程安全的。
public String reverse3(String str) {
//异常情况处理
if (str == null || str.length() <= 1) {
return str;
}
StringBuilder stringBuilder = new StringBuilder(str).reverse();
return stringBuilder.toString();
}
解法四:使用栈的方法实现
字符串反转过程,有点类似堆栈的操作,将字符串push到堆栈中,然后在pop出来,采用先进后出,实现字符串的反转。
public String reverse(String str) {
//异常情况处理
if (str == null || str.length() <= 1) {
return str;
}
char[] array = str.toCharArray();
Stack<Character> stack = new Stack<Character>();
for (char c:array) {
stack.push(c);
}
//使用length暂存堆的大小,因为遍历的过程中,会改变堆的大小
int length = stack.size();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < length; i++) {
builder.append(stack.pop());
}
return builder.toString();
}
在这个实现中,使用了StringBuilder来保存字符串。如果你使用String类型做拼接,会影响效率,想想为什么?
总结
这里列出的四种比较经典的字符串反转的实现方法,从效率上分析,实现1和效率3效率应该比较高,这块需要查看一下StringBuilder的源码。但如果面试时,能列出这几种算法并对比一下,应该会给面试官比较深的印象。