重新排列(交换)数组值

时间:2019-01-02 11:53:34

标签: java arrays

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

  

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

     
      
  • 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;
    }

1 个答案:

答案 0 :(得分:0)

当前实现的伪代码为:

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;
        }
    }
}

当您尝试配对的4之后没有3出现 时,失败的测试用例将失败。根据预期的产量

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

您的代码还必须能够移动出现在您当前正在使用的4之前的3,如下面的第二个交换所示:< / p>

        ↔↔ 
       ↕  ↕
[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;
}