【问题标题】:Rearranging (swapping) array values重新排列(交换)数组值
【发布时间】:2019-01-02 11:53:34
【问题描述】:

我正在尝试解决 CodingBat 的 fix34 问题:

返回一个数组,其中包含与给定数组完全相同的数字,但重新排列,以便每个 3 后面紧跟一个 4。不要移动 3,但每个其他数字都可以移动。该数组包含相同数量的 3 和 4,每个 3 后面都有一个不是 3 的数字,并且 3 出现在数组中任何 4 之前。

  • fix34([1, 3, 1, 4]) → [1, 3, 4, 1]
  • fix34([1, 3, 1, 4, 4, 3, 1]) → [1, 3, 4, 1, 1, 3, 4]
  • fix34([3, 2, 2, 4]) → [3, 4, 2, 2]

我的代码适用于所有情况,除了:

1. fix34([1, 3, 1, 4, 4, 3, 1])
       → [1, 3, 4, 1, 1, 3, 4] (Expected)
         [1, 3, 4, 1, 4, 3, 1] (Actual Output)

2. fix34([5, 3, 5, 4, 5, 4, 5, 4, 3, 5, 3, 5])
       → [5, 3, 4, 5, 5, 5, 5, 5, 3, 4, 3, 4] (Expected)
         [5, 3, 4, 5, 5, 4, 5, 4, 3, 5, 3, 5] (Actual Output)

似乎无法弄清楚为什么,提前谢谢!

public int[] fix34(int[] nums) {
      
      int [] result = new int [nums.length];
      int temp = 0;
      for(int i = 0; i < nums.length; i++){
        if(nums[i] == 3){
          result[i] = 3;
          for(int j = i + 1; j < nums.length; j++){
            if(nums[j] == 4){
              temp = nums[i + 1];
              result[i + 1] = 4;
              result[j] = temp;
              nums[j] = temp;
              break;
            }
          }
        }else if(result[i] == 0){
          result[i] = nums[i];
        }
      }
      return result;
    }

【问题讨论】:

  • 请不要指望我们熟记所有的编码挑战/竞赛。告诉我们代码应该做什么,它实际做什么,以及你不清楚的部分。
  • 是的,请edit 提出您的问题,以说明您的代码对您列为“我的代码适用于所有情况除外”的两种情况产生了什么。

标签: java arrays


【解决方案1】:

您当前实现的伪代码是:

for (each_element_in_nums) {
    if (that_element_is_a_3) {
        scan_the_following_elements_for_a_4;
        if (we_found_a_4) {
            swap_that_4_with_the_element_immediately_following_the_3;
        }
    }
}

当您尝试配对的3之后没有出现4 时,不成功的测试用例将失败。基于预期输出

1. fix34([1, 3, 1, 4, 4, 3, 1])
       → [1, 3, 4, 1, 1, 3, 4] (Expected)

您的代码还必须能够移动出现在您当前正在处理的3 之前的4,如下面的第二次交换所示:

        ↔↔ 
       ↕  ↕
[1, 3, 1, 4, 4, 3, 1]
             ↕     ↕
              ↔↔↔↔↔ 

换句话说,您当前的代码只能将4 向左移动。您还需要能够将4 向右移动。

这是一个相当简单的实现,似乎可以解决问题:

/**
 * Returns an array with elements rearranged.
 * <p>
 * Rules:<br>
 * 1. [input] The array contains the same number of 3's and 4's.<br>
 * 2. [input] Every 3 has a number after it that is not a 3.<br>
 * 3. [input] A 3 appears in the array before any 4.<br>
 * 4. [output] Return an array that contains exactly the same numbers as the
 *             given array, but rearranged so that every 3 is immediately 
 *             followed by a 4.<br>
 * 5. [output] Do not move the 3's, but every other number may move.<br>
 */
public static int[] fix34(int[] nums) {
    if (nums.length > 0 && nums[nums.length - 1] == 3) {
        // bulletproofing: Really should not happen, per rule #2
        throw new IllegalArgumentException("Input array cannot end with a 3");
    }
    List<Integer> positionOf3s = new ArrayList<>();
    List<Integer> positionOf4s = new ArrayList<>();
    int[] result = nums.clone();
    for (int resultArrayIndex = 0; resultArrayIndex < result.length; resultArrayIndex++) {
        if (result[resultArrayIndex] == 4) {
            positionOf4s.add(resultArrayIndex); // position of swap candidate
        } else if (result[resultArrayIndex] == 3) {
            if (result[resultArrayIndex + 1] == 3) {
                // bulletproofing: Really should not happen, per rule #2
                throw new IllegalArgumentException("Input array cannot contain two successive 3's");
            } else if (result[resultArrayIndex + 1] == 4) {
                // 3 already paired with 4, so no need to move, just skip the 4
                resultArrayIndex++;
            } else {
                // this 3 is lonely, so add its position to the list to be paired
                positionOf3s.add(resultArrayIndex);
            }
        }
    }
    if (positionOf3s.size() > positionOf4s.size()) {
        // bulletproofing: Really should not happen per rule #1
        throw new IllegalArgumentException(
                String.format("3's needing to be paired: %d; 4's available for swapping: %d",
                        positionOf3s.size(), positionOf4s.size()));
    }
    /*
     * perform swap for each "lonely" 3 in listOf3sIndex, using the corresponding
     * swap candidate from positionOf4s
     */
    for (int listOf3sIndex = 0; listOf3sIndex < positionOf3s.size(); listOf3sIndex++) {
        result[positionOf4s.get(listOf3sIndex)] = result[positionOf3s.get(listOf3sIndex) + 1];
        result[positionOf3s.get(listOf3sIndex) + 1] = 4;

    }
    return result;
}

【讨论】:

    猜你喜欢
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 2015-10-31
    • 1970-01-01
    • 2012-08-11
    相关资源
    最近更新 更多