我正在尝试解决这个CodingBat问题:
(这是一个稍微难以修复的版本问题。)返回一个包含与给定数组完全相同的数字的数组,但重新排列,以便每4个后面紧跟一个5.不要移动4,但是每隔一个号码都可以移动。该数组包含相同数量的4和5,并且每4个数字后面都有一个不是4的数字。在这个版本中,5可能出现在原始数组中的任何位置。
fix45({5, 4, 9, 4, 9, 5}) → {9, 4, 5, 4, 5, 9}
fix45({1, 4, 1, 5}) → {1, 4, 5, 1}
fix45({1, 4, 1, 5, 5, 4, 1}) → {1, 4, 5, 1, 1, 4, 5}
我最初使用的方法通过了所有网站测试,但我认为它不适用于更长的数组。初始方法使用了2个循环并且没有使用新数组。我已经创建了一个引入新数组和第三个嵌套循环的解决方案,我相信它将适用于所有问题实例。但是,该网站声明本节中的问题可以通过2个循环来解决,所以我想知道是否确实有一个2循环解决方案可以用于任何问题的实例。这是问题和我的3循环解决方案:
public int[] fix45(int[] nums) {
int[] locations = {-1};
for (int i = 0; i < nums.length - 1; ++i) {
if (nums[i] == 4) {
JLoop:
for (int j = nums.length-1; j >= 0; --j) {
if (nums[j] == 5) {
for (int k = locations.length-1; k>=0 ; --k) {
if (locations[k] == j) {
continue JLoop;
}
}
nums[j] = nums[i + 1];
nums[i + 1] = 5;
locations[locations.length - 1] = i+1;
locations = java.util.Arrays.copyOf(locations,
locations.length + 1);
locations[locations.length-1] = -1;
break;
}
}
}
}
return nums;
}
答案 0 :(得分:6)
每次发现4时,从阵列的一端重新开始搜索合适的5似乎很浪费。阵列的一部分已经被扫描,并且已知不包含可以移动的5。这是O(n)时间和O(1)空间。
public static int[] fix45(int[] nums) {
int j = 0;
for (int i = 0; i < nums.length - 1; ++i) {
if (nums[i] == 4 && nums[i + 1] != 5) {
/*
* Need to find the next movable 5 That means an element that is 5 and
* either is the first element or is preceded by anything other than 4
*/
while (nums[j] != 5 || (j != 0 && nums[j - 1] == 4)) {
j++;
}
nums[j] = nums[i + 1];
nums[i + 1] = 5;
}
}
return nums;
}
答案 1 :(得分:3)
使用额外的阵列,这是一个带有&#34;一个循环的解决方案&#34; (没有嵌套循环的循环):
public int[] fix45(int[] nums) {
int[] otherValues = new int[nums.length];
for(int i = 0, c = 0; i < nums.length; i++)
if(nums[i] != 4 && nums[i] != 5)
otherValues[c++] = nums[i];
for(int i = 0, c = 0; i < nums.length; i++)
if(nums[i] == 4)
nums[++i] = 5;
else
nums[i] = otherValues[c++];
return nums;
}
我们修好四肢,取出非四肢和非四肢,并将所有值全部按顺序排列。
为了改善空间使用(可能不是很多),你可以在制作额外数组之前计算四个数量。
答案 2 :(得分:1)
public int[] fix45(int[] nums) {
int t=0;
for(int i=0; i< nums.length ; i++)
for(int j=0;j<nums.length ; j++)
if(nums[i]==5 && nums[j]==4)
{
t=nums[j+1];
nums[j+1]=nums[i];
nums[i]=t;
}
return nums;
}
答案 3 :(得分:0)
public int[] fix45(int[] nums) {
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 5 && i == 0 || nums[i] == 5 && nums[i - 1] != 4) {
int a5 = i;
for (int j = 0; j < nums.length; j++) {
if (nums[j] == 4 && nums[j + 1] != 5) {
int temp = nums[j + 1];
nums[j + 1] = 5;
nums[a5] = temp;
break;
}
}
}
}
return nums;
}
答案 4 :(得分:0)
folder('project-a') {
description('Folder for project A')
}
答案 5 :(得分:0)
它也可以在while循环中完成!
public int[] fix45(int[] nums) {
int start = 0;
int end = nums.length-1;
boolean is4 = false;
boolean is5 = false;
while( start < nums.length ){
if(nums[start] == 4 && nums[start+1]!=5){
is4 = true;
}
if(nums[end] == 5 && (end == 0 || (end-1>=0 && nums[end-1]!=4))){
is5 = true;
}
if(is4 && is5){
int temp = nums[start+1];
nums[start+1] = nums[end];
nums[end] = temp;
is4 = false;
is5 = false;
end = nums.length-1;
}
if(is4){
end--;
continue;
}
start++;
}
return nums;
}
答案 6 :(得分:0)
这是一个简单的答案:)
public int[] fix45(int[] nums) {
int p5=0;//tracker for 5's
for(int i=0;i<nums.length;i++){
if(nums[i] == 4){// got a 4
for(int j = p5 ;j<nums.length;j++){
//finding a 5 for that 4 at nums[i]
if(nums[j] == 5 && ( (j > 0 && nums[j-1]!=4 ) || (j==0) )){
// found 5 and checking if it is not preceded by a 4
//swap if not preceded by a 4
int temp = nums[i+1];
nums[i+1] = nums[j];
nums[j] = temp;
p5 = j;//set the tracker to where we found 5 for nums[i]
break;//break out of loop
}
}
}
}
return nums;
}
答案 7 :(得分:0)
我只想添加我的解决方案,因为我已经在CodingBat上进行了测试并通过了所有测试,并且没有使用2 for循环
public int[] fix45(int[] nums) {
if (nums.length == 0 || nums.length == 1 || nums.length == 2) {
return nums;
}
int indexof4 = 0, indexof5 = 0;
int indexToWorkonForRplcmnt = -1;
while (indexof4 < nums.length && indexof5 < nums.length) {
if ((indexof4 + 1) < nums.length && nums[indexof4] == 4 && nums[indexof4 + 1] != 5) {
indexToWorkonForRplcmnt = indexof4 + 1;
// System.out.println("IndexOf4:"+indexToWorkonForRplcmnt);
} else {
indexof4++;
}
if ((indexof5) < nums.length && nums[indexof5] == 5) {
if (indexof5 == 0 && nums[indexof5] == 5) {
// System.out.println("IndexOf5:"+indexof5);
} else if (nums[indexof5 - 1] != 4 && nums[indexof5] == 5) {
// System.out.println("IndexOf5:"+indexof5);
} else {
indexof5++;
}
} else {
indexof5++;
}
if (indexToWorkonForRplcmnt != -1 && (indexof5) < nums.length && nums[indexof5] == 5) {
System.out.println("IndexOf4:" + indexToWorkonForRplcmnt);
System.out.println("IndexOf5:" + indexof5);
int temp = nums[indexToWorkonForRplcmnt];
nums[indexToWorkonForRplcmnt] = nums[indexof5];
nums[indexof5] = temp;
indexToWorkonForRplcmnt = -1;
indexof4++;
indexof5++;
}
}
return nums;
}
答案 8 :(得分:0)
这里有很多复杂的代码。我认为我们是这样简化的:
public int[] fix45(int[] nums) {
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 4) {
for (int j = 0; j < nums.length; j++) {
if (nums[j] == 5) {
if (j > 0 && nums[j - 1] != 4) {
int tmp = nums[i + 1];
nums[i + 1] = 5;
nums[j] = tmp;
} else if (j == 0) {
int tmp = nums[i + 1];
nums[i + 1] = 5;
nums[j] = tmp;
}
}
}
}
}
return nums;
}
答案 9 :(得分:0)
import java.util.Arrays;
public class Fix45 {
public static void main(String[] args) {
assertArrays(new int[]{9, 4, 5, 4, 5, 9}, new int[]{5, 4, 9, 4, 9, 5});
assertArrays(new int[]{1, 4, 5, 4, 5}, new int[]{5, 4, 5, 4, 1});
assertArrays(new int[]{1, 1, 4, 5, 4, 5}, new int[]{5, 5, 4, 1, 4, 1});
assertArrays(new int[]{4, 5, 4, 5, 1}, new int[]{4, 5, 4, 1, 5});
assertArrays(new int[]{4, 5, 4, 5, 2}, new int[]{4, 2, 4, 5, 5});
}
public static int[] fix45(int[] nums) {
for (int i = 0; i < nums.length; i++) {
if(nums[i] == 4 && nums[i + 1] != 5){
int location = i + 1;
for (int j = 0; j < nums.length; j++) {
if(nums[j] == 4 && nums[j + 1] == 5){
j++;
continue;
}
if (nums[j] == 5) {
int temp = nums[j];
nums[j] = nums[location];
nums[location] = temp;
}
}
}
}
return nums;
}
private static void assertArrays(int[] expected, int[] input) {
int[] actual = fix45(input);
System.out.println(Arrays.toString(actual));
boolean status = Arrays.equals(expected, actual);
System.out.println(status);
}
}
答案 10 :(得分:0)
此解决方案使用LinkedHashSet。我认为时间的O-表示法是 O(n),而空间也是 O(n)。
public int[] fix45(int[] nums) {
Set<Integer> ind4 = new LinkedHashSet<>();
Set<Integer> ind5 = new LinkedHashSet<>();
//Store positions for all fours and fives except those fives
//that immediately follow number four.
for (int i = 0; i < nums.length; ++i) {
if (nums[i] == 4){
ind4.add(i);
if (i + 1 < nums.length && nums[i + 1] == 5){
i++;
}
}else if (nums[i] == 5){
ind5.add(i);
}
}
Iterator<Integer> iter5ind = ind5.iterator();
for (Integer i : ind4){
if (i + 1 > nums.length || !iter5ind.hasNext()) break;
if (nums[i + 1] == 5){
continue;
}
int j = iter5ind.next();
int tmp = nums[i + 1];
nums[i + 1] = nums[j];
nums[j] = tmp;
}
return nums;
}
答案 11 :(得分:0)
这是一个我找到的简单解决方案。 只需创建跟踪4和5的ArrayLists,然后交换值。 这怎么容易理解?
public int[] fix45(int[] nums)
{
//Create a copy array to manipulate and eventually return.
int[] ret = nums;
//Create two ArrayLists that let us track for and five positions.
ArrayList<Integer> fourPositions = new ArrayList<Integer>();
ArrayList<Integer> fivePositions = new ArrayList<Integer>();
//Get the positions of fours and fives and add them to their respective ArrayLists.
for (int i = 0; i < ret.length; i++)
{
if (ret[i] == 4)
{
fourPositions.add(i);
}
if (ret[i] == 5)
{
fivePositions.add(i);
}
}
//Swap all of the places right after the fours with a respective number of the fives,
for (int i = 0; i < fourPositions.size(); i++)
{
int temp = ret[fourPositions.get(i) + 1];
ret[fourPositions.get(i) + 1] = ret[fivePositions.get(i)];
ret[fivePositions.get(i)] = temp;
}
//Return the array.
return ret;
}
答案 12 :(得分:0)
在dansalmos评论后修复:
public int[] fix45(int[] nums) {
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 4) {
if(nums[i+1] == 5) continue;
for( int j = 0; i < nums.length; j++){
if(nums[j] == 5 && (j==0 || nums[j-1] != 4)){
nums[j] = nums[i+1];
nums[i+1] = 5;
break;
}
}
}
}
return nums;
}
答案 13 :(得分:0)
public int[] fix45(int[] nums)
{
for(int i=0; i<nums.length; i++)
{
if(nums[i]==5)
{
for(int j=0; j<nums.length; j++)
if(nums[j]==4&&nums[j+1]!=5)
{
f(nums, i, j+1);
}
}
}
return nums;
}
///this "helper" function swaps 2 elements of the array
public void f(int []nums , int m, int n)
{
int t= nums[m];
nums[m] =nums[n];
nums[n] = t;
}
答案 14 :(得分:0)
我意识到这个帖子已经有好几年了,但我只想添加我的解决方案:
public int[] fix45(int[] nums){
int notAFourOrFive = 0;
int[] ary = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 4) {
ary[i] = 4;
ary[i+1] = 5;
}
else if (nums[i] != 5) {
notAFourOrFive = nums[i];
}
}
for (int j = 0; j < ary.length; j++) {
if (ary[j] == 0) {
ary[j] = notAFourOrFive;
}
}
return ary;
}
看到4
和5
的数量相等,只要找到4
,就可以将它们添加到新数组中。在这种情况下使用i+1
是安全的,因为4
永远不会出现在数组的末尾。设置其他&#39;也是安全的。每当到达非4
或非5
时,就会出现数字,因为在每次测试中所有其他数字都是相同的。
答案 15 :(得分:0)
public int[] fix45(int[] nums) {
if (nums.length < 2) {
return nums;
}
int index = 0;
int index2 = 0;
int index3 = 0;
int[] only5 = fives(nums);
int[] after4 = new int[count4(nums)];
for (int a = 0; a < nums.length - 1; a++) {
if (nums[a] == 4) {
after4[index] = nums[a + 1];
index++;
nums[a + 1] = only5[index2];
index2++;
}
}
//This while loop gets the frst number that is not a 5 that is after a 4
while (nums[0] == 5) {
nums[0] = after4[index3];
index3++;
}
if (nums[nums.length - 2] != 4 && nums[nums.length - 1] == 5) {
nums[nums.length - 1] = after4[index3];
index3++;
}
for (int b = 1; b < nums.length; b++) {
if (nums[b] == 5 && nums[b - 1] != 4) {
nums[b] = after4[index3];
index3++;
}
}
return nums;
}
public int count4(int[] nums) {
int cnt = 0;
for (int e : nums) {
if (e == 4) {
cnt++;
}
}
return cnt;
}
public int[] fives(int[] nums) {
int index = 0;
int[] only5 = new int[count4(nums)];
for (int e : nums) {
if (e == 5) {
only5[index] = e;
index++;
}
}
return only5;
}
//长解决方案,向上滚动
答案 16 :(得分:0)
public int[] fix45(int[] nums) {
int idx4 = -1;
int idx5 = -1;
while (true) {
while (true) { // find a 4 without a 5 after it
idx4 = find(nums, 4, ++idx4);
if (idx4 == -1) // done if no more 4's
return nums;
if (nums[idx4+1] != 5)
break;
}
while (true) { // find a 5 without a 4 before it
idx5 = find(nums, 5, ++idx5);
if (idx5 == 0 || nums[idx5-1] != 4)
break;
}
nums[idx5] = nums[idx4+1]; // swap the 4 and 5
nums[idx4+1] = 5;
}
}
public int find(int[] nums, int num, int start) {
for (int i = start; i < nums.length; i++)
if (nums[i] == num)
return i;
return -1;
答案 17 :(得分:0)
以下方法将使用O(n)空间在O(n)时间运行:
public int[] fix45(int[] nums) {
if (nums == null || nums.length <= 1) {
return nums;
}
// store all the 5s pos
int[] pos = new int[nums.length];
int j = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 5) {
pos[j++] = i;
}
}
j = 0;
for (int i = 0; i <= nums.length - 2; i++) {
if (nums[i] == 4 && nums[i + 1] != 5) {
if (j >= pos.length) {
System.err
.println("No more 5s: there are more 4 than 5 in the input array");
break;
}
// fix45 swapping
nums[pos[j++]] = nums[i + 1];
nums[i + 1] = 5;
}
}
return nums;
}