改进此代码以反转字符串并删除重复的字符

时间:2014-05-23 10:32:27

标签: java algorithm

我最近参加了一次采访,我被要求编写一个程序。 问题是:

  

拿一根绳子。 " 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);
    }
}

我如何改进上述内容?

3 个答案:

答案 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);
}

}