我正在尝试解决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;
}
答案 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;
}