问题是从Java中的codingBat解决this问题 .
Problem Statement:
返回一个包含与给定数组完全相同的数字的数组,但重新排列,以便所有偶数都在所有奇数之前 . 除此之外,数字可以是任何顺序 . 您可以修改并返回给定的数组,或者创建一个新数组 .
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循环?不要使用收藏!
My solution:
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 回答
保持你的限制,这是一个单循环的答案:
由于允许创建新数组,并且数字的顺序无关紧要,我将使用以下方法:
更新:一个不太可读的版本,不需要额外的数组(沿着@Seelenvirtuose建议的方式,只是没有额外的循环)
您不需要任何临时列表或数组,因为您可以在原位重新排序元素 .
这是一个简单的算法:
定义左右两个指针(最初设置为数组的边界) .
只要左边不超过右边且
nums[left]
是偶数,向左递增 .只要右边不超过左边,
nums[right]
是奇数,右边减少 .如果左侧仍然小于右侧,则交换左右位置的元素 .
只要左边仍然小于右边,重复2,3,4 .
得到它了?这里有一些代码:
好的!我终于跳过了这个实际上已经关闭的question但是问我的解决方案几乎是在我解决的2个案例中失败了:
我在问题中看到了一个问题代码,它在几个案例中使它失败了 .
我认为以下是最简单,最优化的解决方案:
对于遇到的每个偶数,遍历evenOdd从0到N.将其复制到evenOdd数组上的所需位置 . 对于遇到的每个奇数,将其存储在一个名为oddnum的独立数组中 . 遍历整个数组后,只需将元素从oddnum复制到evenOdd的Back .
例如:evenOdd = {5,2,1,4}步骤1.复制5到oddnum [0] 2.复制2到evenodd [0] 3.复制1到oddnum [1] 4.复制1到evenodd [1] 5. cpy oddnum [0] to evenOdd [2]和oddnum [1] to evenOdd [3]
就地版本(稳定):
我们不断搜索te第一个和最后一个无效值(第一个奇数,在最后一个偶数之前)并继续交换它们直到它们交叉:
辅助设备(稳定):
我们在单独的列表中对偶数和奇数值进行分区并将它们连接起来: