我最近参加了一次采访,我被要求编写一个程序。 问题是:
拿一根绳子。 " Hammer",例如 反转它,任何角色都不应重复 因此,输出将是 - " remaH"。
这是我给出的解决方案:
public class Reverse {
public static void main(String[] args) {
String str = "Hammer";
String revStr = "";
for(int i=0; i<=str.length()-1;i++){
if(revStr.indexOf(str.charAt(i))==-1){
revStr = str.charAt(i)+revStr;
}
}
System.out.println(revStr);
}
}
我如何改进上述内容?
答案 0 :(得分:3)
问题是String是不可变对象,当使用operator+
将char与当前结果连接起来时,实际上是创建了一个新字符串。
这会导致创建长度为1+2+...+n
的字符串,从而为您提供O(n^2)
的总体性能(除非编译器为您优化)。
使用StringBuilder
而不是连接字符串将为您提供O(n)
性能,并且还有更好的常量。
请注意,StringBuilder
提供了有效的append()
实现,因此您需要向其附加元素,而不是将它们添加到StringBuilder
的头部。
您还应该重新考虑indexOf()
的使用情况 - 如果字符根本不能出现两次,请考虑使用Set<Chatacter>
来维护“已使用”字符列表,如果它可以出现两次,但不能一个接一个(例如“mam”有效) - 首先不需要indexOf()
,只需检查最后读取的字符。
答案 1 :(得分:0)
这是一个不使用任何stringbuilder或中间String对象的解决方案,只是将字符串视为字符数组;这应该更有效率。
import java.util.Arrays;
public class Reverse {
public static void main(String[] args) {
String str = "Hammer";
String revStr = null;
char [] chars = str.toCharArray();
char [] reversedChars = new char[chars.length];
// copy first char
reversedChars[reversedChars.length - 1] = chars[0];
// process rest
int r = reversedChars.length - 2;
for(int i = 1 ; i < chars.length ; i++ ){
if(chars[i] != chars[i-1]){
reversedChars[r] = chars[i];
r--;
}
}
revStr = new String(Arrays.copyOfRange(reversedChars, r+1, reversedChars.length));
System.out.println(revStr);
}
答案 2 :(得分:-1)
package com.in.main;
public class Reverse {
public static void main(String[] args) {
String str = "Hammer";
StringBuilder revStr= new StringBuilder("");
for(int i=str.length(); i>=0;i--){
if(revStr.indexOf(str.charAt(i))==-1){
revStr.append(str.charAt(i));
}
}
System.out.println(revStr);
}
}