如果输入数组为 - 1,4,3,8,6,5,7,则输出应为 - 4 8 6 1 3 5 7
我有一个插入类型的解决方案。
void sortarrayinorder(int arr[],int size)
{
int i,j,tem,k;
for(i=1;i<size;i++)
{
for(j=0;j<i;j++)
{
if((arr[j]%2)!=0 && (arr[i]%2)==0)
{
tem=arr[j];
arr[j]=arr[i];
for(k =i;k>j;k--)
arr[k]=arr[k-1];
arr[k+1]=tem;
}
}
}
}
能否以更好的方式解决这个问题?我的解决方案的复杂性是o(n2)。请提供时间复杂度较低的解决方案。不允许有额外的空间。
答案 0 :(得分:2)
只要您允许分配单独的输出缓冲区,就可以使用两遍方法在O(n)
中执行此操作。在第一遍中,检测并复制所有偶数。在第二遍,检测并复制所有奇数。
答案 1 :(得分:1)
class Program
{
static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5,6,7,8,9,10,11,12,13,14 };
//using delegate
Array.Sort (numbers, (x, y) => x % 2 == y % 2 ? 0 : x % 2 == 1 ? -1 : 1);
Array.ForEach(numbers, x => Console.Write(x));
Console.WriteLine("");
//using custom comparer
CustomComparer comparer = new CustomComparer();
Array.Sort(numbers, comparer);
Array.ForEach(numbers, x => Console.Write(x));
Console.WriteLine("");
//using lambda
int[] items = numbers.OrderBy(x => x % 2 == 0).ThenBy(x => x % 2).ToArray();
Console.WriteLine("");
Array.ForEach(items, x => Console.Write(x));
}
public int Compare(int x, int y)
{
return x % 2 == y % 2 ? 0 : x % 2 == 1 ? -1 : 1;
}
}
public class CustomComparer : IComparer<int>
{
int IComparer<int>.Compare(int x, int y)
{
return x % 2 == y % 2 ? 0 : x % 2 == 1 ? -1 : 1;
}
}
答案 2 :(得分:1)
如果不使用额外空间,可以在O(n log n)
时间内完成。策略是首先在O(n log n)
时间对数组进行排序,然后通过两次连续的线性扫描将数组划分为偶数和奇数组,每次扫描都采用O(n)
。
总复杂度为O(n log n) + 2 * O(n) = O(n log n)
。
如果我们有关于数组中数字分布的更多信息,则可以通过降低整体复杂性来改善对阵列进行排序所需的O(n log n)
时间。
可以在http://www.codeblocks.info/2010/10/sorting-array-with-all-even-numbers.html
看到此代码答案 3 :(得分:0)
您当然可以使用O(n)
额外内存在O(n)
时间内完成此操作。你需要一个稳定的排序,实际上你需要做一个MSD基数排序的第一步(通常标志位是“最重要”位,而你对偶数/奇数感兴趣,但它是相同的基本交易) 。通过使用单独的缓冲区包含1或0值,然后将它们组合,可以使基数排序稳定。
C ++有算法stable_partition
,它完全符合您的要求。如果它使用缓冲区,则O(n)
复杂度;如果不使用缓冲区,则O(n log n)
。我不知道后者的技术。我意识到这个问题是关于C的,但是你可以从任何C ++标准库实现中复制和修改代码,或者使用C ++编译器来构建一个调用"extern C"
的{{1}}函数。