【问题标题】:create a function that returns an array strings rearranged as a palindrome创建一个函数,该函数返回重新排列为回文的数组字符串
【发布时间】:2015-09-13 18:50:46
【问题描述】:

我正在尝试编写一个函数,该函数将一个只有小写字母的字符串数组作为输入。函数返回一个相同字符串的数组,但每个字符串的字母都重新排列,如果可能,它会变成回文,如果不是,则返回 -1。

public static Object buildPalin(String[] arrayOfStrings) 
{
    String[] palindrome = new String[arrayOfStrings.length];
    int offset = 0; 

    int charWithoutReflection = 0; 
    List<String> whole= Arrays.asList(arrayOfStrings);
    String wholeString = String.join("", whole);

    for(int i=0; i< arrayOfStrings.length; i++) 
    { 
        if (arrayOfStrings[i] != "") 
        { 
            int currentCharPosition = wholeString.indexOf(arrayOfStrings[i], 
            i + 1); 

            if (currentCharPosition != -1)
            { 
                palindrome[offset] = arrayOfStrings[i]; 
                palindrome[palindrome.length - 1 - offset] = 
                arrayOfStrings[i]; 
                arrayOfStrings[currentCharPosition] = ""; 
                arrayOfStrings[i] = ""; 
            }
            else {
                if (charWithoutReflection > 0) 
                    return -1; 
                palindrome[palindrome.length/2] = arrayOfStrings[i]; 
                charWithoutReflection++; 
            }
            offset++; 
        }
    } 
    return palindrome;
   } 

这个函数适用于输入数组是这样的情况 {“a”、“b”、“a”} {"a","b","c"} 等等。

但是当我有如下输入时: {"aba", "bb", "cac"} 和这样的字符串数组失败了。

对此的任何指导或建议都会有所帮助。

注意: 这不是课堂作业,而是我在面试中被问到的一个问题。 我能够提出上述解决方案,但现在我正试图使其也适用于角落案例。这对以后的面试很有帮助。

===============================根据以下 Eric 的评论更新代码=========

public static Object build(String[] arrayOfStrings) {
   String[] palindrome = new String[arrayOfStrings.length];
   int offset = 0; 
   int charWithoutReflection = 0; 
   List<String> whole= Arrays.asList(arrayOfStrings);
   String wholeString = String.join("", whole);

   for(int i=0; i< arrayOfStrings.length; i++) 
   { 
      if (arrayOfStrings[i] != "") { 
        int currentCharPosition = wholeString.indexOf(arrayOfStrings[i], i + 
        1); 

        if (currentCharPosition != -1)
        { 
          palindrome[offset] = arrayOfStrings[i]; 
          palindrome[palindrome.length - 1 - offset] = arrayOfStrings[i]; 
          arrayOfStrings[currentCharPosition] = ""; 
          arrayOfStrings[i] = ""; 
        }
        else {
          if (charWithoutReflection > 0) 
          {
             System.out.println("failed case");
             return -1;
          }
          palindrome[palindrome.length/2] = arrayOfStrings[i]; 
          charWithoutReflection++; 
        }
        offset++; 
        }
    } 
    return palindrome;
  }

  // code from main function calling above function is:
  public static void main(String[] args) {
    String a[] = {"abb"};
    for ( int j = 0; j < a.length ; j++)
    {
      String[] tokens = a[j].split("");

      System.out.println(Arrays.deepToString((Object[]) build(tokens)));    

    }

产生错误的输出为 : ( 对于输入 [a,b,b]

[null, b, null] 而不是 [b, a, b]

【问题讨论】:

  • 你的代码不可能为{"a", "b", "a"} {"a","b","c"}工作。这是String 的二维数组。你的方法只需要一个一维数组。
  • 或者这两个不同的输入数组示例是否有效?这是有道理的。
  • @ErickG.Hagstrom:是的,两个不同的数组示例(不是二维数组)。两者都是不同的输入。只是想展示它工作正常的案例以及哪些案例代码不起作用。
  • wholeString 变量的用途是什么?如果您只是想重新排列每个输入 String 的字母,则无需将所有这些 Strings 视为一个大 String

标签: java arrays algorithm palindrome


【解决方案1】:

我认为您应该将解决方案拆分为两个单独的情况,即奇数情况和偶数情况。对于这两种情况,都做一个频率字符的计数数组。

 First Case:
    1) Check that all chars have even count but one.
    2) Create a stringBuffer and append the odd char and decrement its count
    3) For each of the remaining characters form your palindrome by adding a char at the front and a char at the end of the string buffer.

 Second Case:
    1) Check that all chars have even counts.
    2) Create a string buffer
    3) For each of the remaining characters from your palindrome as case one.

【讨论】:

    【解决方案2】:

    对于每个String,将其转换为已排序的List 或字符数组。然后逐个字符地浏览列表,计算每个字符出现的次数。如果数字 (n) 是奇数,则将出现 n 个字符插入到输出 String 的中间。如果 n 是偶数,则将 n/2 放在输出 String 的开头,并将 n/2 放在末尾。如果遇到两个以上出现奇数的字符,则必须返回 -1。当您到达列表末尾时,将输出 String 放入输出数组中。如果你一直通过,返回那个数组。

    public static Object build(String[] arrayOfStrings) {
        String[] palindrome = new String[arrayOfStrings.length];
    
        for (int i = 0; i < arrayOfStrings.length; i++) {
        String currentString = arrayOfStrings[i];
        if (currentString.isEmpty()) {
            palindrome[i] = currentString;
        } else {
            char[] chars = Arrays.copyOf(currentString.toCharArray(),
                currentString.length() + 1);
            chars[currentString.length()] = Character.MAX_VALUE;
            Arrays.parallelSort(chars);
    
            char currentChar = chars[0];
            int count = 1;
            boolean foundOdd = false;
            String newString = "";
            for (int j = 1; j < chars.length; j++) {
                if (chars[j] == currentChar) {
                    count++;
                } else {
                    if (foundOdd) {
                        if (count % 2 == 0) {
                            newString = even(newString, currentChar, count);
                        } else {
                            return -1;
                        }
                    } else {
                        if (count % 2 == 0) {
                            newString = even(newString, currentChar, count);
                        } else {
                            foundOdd = true;
                            newString = odd(newString, currentChar, count);
                        }
                    }
                    count = 1;
                    currentChar = chars[j];
                }
            }
            palindrome[i] = newString;
            newString = "";
            }
        }
        return palindrome;
    }
    
    private static String even(String oldString, char currentChar, int count) {
        assert count % 2 == 0;
        int halfCount = count / 2;
        String occurrences = "";
        for (int i = 0; i < halfCount; i++) {
            occurrences += currentChar;
        }
        return occurrences + oldString + occurrences;
    }
    
    private static String odd(String oldString, char currentChar, int count) {
        assert count % 2 == 1;
        int length = oldString.length() / 2;
        String occurrences = "";
        for (int i = 0; i < count; i++) {
            occurrences += currentChar;
        }
        return oldString.substring(0, length) + occurrences
            + oldString.substring(length);
    }
    
    // code from main function calling above function is:
    public static void main(String[] args) {
        String a[] = { "abb", "aaaabbcccddddeeffgghhii" };
        Object result = build(a);
        if (result.equals(-1)) {
            System.out.println("Failed to find a palindrome for at least one of the input values");
        } else {
            String[] resultStr = (String[]) result;
            for (int i = 0; i < resultStr.length; i++) {
                System.out.println(resultStr[i]);
            }
        }
    }
    

    上面的代码太可怕了。一方面,它严重依赖String 连接。但它有效。

    【讨论】:

    • 我尝试按照您的建议进行更改,但在“abb”的情况下失败,它产生的输出为 ===> [ null, b , null ]。使用最新代码更新问题。
    猜你喜欢
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多