用Java中的一个循环解决codingBat'noddd'

时间:2014-06-05 08:35:57

标签: java

问题是关于在Java中解码来自codingBat的this问题。

问题陈述:

返回一个包含与给定数组完全相同的数字的数组,但重新排列,以便所有偶数都在所有奇数之前。除此之外,数字可以是任何顺序。您可以修改并返回给定的数组,也可以创建一个新数组。

  

evenOdd({1,0,1,0,0,1,1})→{0,0,0,1,1,1,1}

     

evenOdd({3,3,2})→{2,3,3}

     

evenOdd({2,2,2})→{2,2,2}

问题很简单,有2个循环,我试图解决它1,它太长了我相信,有没有其他有效的方法来解决上述问题使用1循环? 不要使用收藏品!

我的解决方案:

public int[] evenOdd(int[] nums) {

boolean oddFound=false;
int count=-1;
int oddGap=0;

for(int i=0;i<nums.length;i++)
  {
     if(!(oddFound)&(nums[i]%2==0))
       continue;

       if((!oddFound)&(nums[i]%2==1))
       {
         oddFound=true;
         count=i;
         continue;
       }
       if((oddFound)&(nums[i]%2==1))
       {
         oddGap++;
         continue;
       }
        if((oddFound)&(nums[i]%2==0)) 
        {
         int temp=nums[count];
         nums[count]=nums[i];  
         nums[i]=temp;

         if(i>0)
             i--;

            if(oddGap>0)
            {
              oddGap--;
              count+=1;
              oddFound=true;
              continue;
             } 
             oddFound=false;
        } 

     }
     return nums;    

}

8 个答案:

答案 0 :(得分:3)

由于允许创建新数组,并且数字的顺序无关紧要,我将使用以下方法:

public int[] evenOdd(int[] nums) {
    int[] output = new int[nums.length];
    int evenPos = 0;
    int oddPos = nums.length-1;
    for (int i : nums) {
        if (i%2==0) {
            output[evenPos++]=i;
        } else {
            output[oddPos--]=i;
        }
    }

    return output;
}

更新:一个不太可读的版本,不需要额外的数组(按照@Seelenvirtuose的建议,只是没有额外的循环)

public int[] evenOdd(int[] nums) {
    int evenPos = 0;
    int oddPos = nums.length-1;
    while (true) {
        if (evenPos>=oddPos || evenPos>=nums.length || oddPos<0) {
            break;
        }

        if (nums[evenPos]%2==0) {
            evenPos++;
        }
        if (nums[oddPos]%2!=0) {
            oddPos--;
        }

        if (evenPos<oddPos && nums[evenPos]%2 != 0 && nums[oddPos]%2 == 0) {
            int tmp = nums[evenPos];
            nums[evenPos] = nums[oddPos];
            nums[oddPos] = tmp;

            oddPos--;
            evenPos++;

        }
    }
    return nums;
}

答案 1 :(得分:2)

您不需要任何临时列表或数组,因为您可以重新排序元素 in-situ

这是一个简单的算法:

  1. 左右定义两个指针(最初设置为数组的边界)。
  2. 只要左边超过并且nums[left]是偶数,则向左递增。
  3. 只要右边超过左边,nums[right]是奇数,右边减少。
  4. 如果左侧仍然小于右侧,则在左右两个位置交换元素。
  5. 只要左边仍然小于右边,重复2,3,4。
  6. 知道了吗?这里有一些代码:

    public int[] evenOdd(int[] nums) {
        // (1)
        int left = 0;
        int right = nums.length -1;
        do {
            // (2)
            while (left < right && nums[left] % 2 == 0)
                left += 1;
            // (3)
            while (right > left && nums[right] % 2 != 0)
                right -= 1;
            // (4)
            if (left < right) {
                int temp = nums[left];
                nums[left] = nums[right];
                nums[right] = temp;
            }
        } while (left < right);   // (5)
        return nums;
    }
    

答案 2 :(得分:1)

好!我终于跳过了这个question实际上已经关闭了,但是问我的解决方案除了在我修复的2个案例中失败之外几乎没有:

我评论了提问者的代码,这个代码在问题中看到的几个案例中都失败了。

我认为以下是最简单,最优化的解决方案:

public int[] evenOdd(int[] nums) {
int y=nums.length,x,a=0;
int temp=0;

for(x=0;x<y;x++)
{
    if(nums[x]%2==0) {
    if(a>(y-2))
       return nums;
    else{
    //nums[a]=nums[a]+nums[x];
    //nums[x]=nums[a]-nums[x];
    //nums[a]=nums[a]-nums[x];

    temp=nums[a];
    nums[a]=nums[x];
    nums[x]=temp;
    a+=1; 
        }

    } 

    return nums; 

    }

答案 3 :(得分:0)

从0到N遍历evenOdd。 对于遇到的每个偶数,将其复制到evenOdd数组上的所需位置。 对于遇到的每个奇数,将其存储在一个名为oddnum的独立数组中。 遍历整个数组后,只需将元素从oddnum复制到evenOdd的Back。

Ex:evenOdd = {5,2,1,4} 步骤1.将5复制到oddnum [0] 2.将2复制到evenodd [0] 3.将1复制到oddnum [1] 4.将1复制到偶数[1] 5. cpy oddnum [0] to evenOdd [2]和oddnum [1] to evenOdd [3]

答案 4 :(得分:0)

遵守您的限制,这是一个单循环的答案:

public int[] evenOdd(int[] nums) {
    int[] result = new int[nums.length];
    int nextEven = 0;
    int nextOdd = nums.length - 1;

    for ( int num : nums )
    {
        if ( num % 2 == 0 )
            result[ nextEven++ ] = num;
        else
            result[ nextOdd-- ] = num;
    }

    return result;
}

答案 5 :(得分:0)

    public int[] evenOdd(int[] nums) {
    int count = 0;
    for (int i = 0; i < nums.length; i++) {

        if (nums[i] % 2 == 0) {

            int temp = nums[i];

            nums[i] = nums[count];
            nums[count] = temp;

            count++;

        }

    }

    return nums;

}

答案 6 :(得分:0)

public int[] evenOdd(int[] nums) {
  Stack stack = new Stack();
  int[] nums2 = new int[nums.length];
  for(int i = 0; i < nums.length; i++) {
    if(nums[i] % 2 != 0) {
      stack.push(nums[i]);
    }
  }
  for(int i = 0; i < nums.length; i++) {
    if(nums[i] % 2 == 0) {
      stack.push(nums[i]);
    }
  }
  for(int i = 0; i < nums.length; i++) {
    nums2[i] = (Integer) stack.pop();
  }
  return nums2;
}

答案 7 :(得分:0)

就地版本(稳定):

我们不断搜索te第一个和最后一个无效值(第一个奇数,在最后一个偶数之前)并继续交换它们直到它们交叉:

public int[] evenOdd(int[] nums) {
  int first = 0, last = nums.length - 1;
  while (first < last) {
    while ((first < last) &&  isOdd(nums[last]))  last--;
    while ((first < last) && !isOdd(nums[first])) first++;
    swap(nums, first, last);
  }
  return nums;
}

boolean isOdd(int num) { return (num & 1) == 1; }
void swap(int[] nums, int i, int j) {
  int copy = nums[i];
  nums[i] = nums[j];
  nums[j] = copy;
}

辅助设备(稳定):

我们在单独的列表中对偶数和奇数值进行分区并将它们连接起来:

public int[] evenOdd(int[] nums) {
  List<Integer> evens = new ArrayList<Integer>(nums.length);
  List<Integer> odds = new ArrayList<Integer>(nums.length);
  for (int num : nums)
    if (isOdd(num)) odds.add(num);
    else evens.add(num);

  int[] results = new int[nums.length];
  int i = 0;
  for (int num : evens) results[i++] = num;
  for (int num : odds) results[i++] = num;
  return results;
}

boolean isOdd(int num) { return (num & 1) == 1; }