类荷兰国旗问题的解决

问题:现有一个数组a[]={3,2,5,8,4,7,6,9};

设有一个数num,要求数组a中的元素大于num的排在数组右边,小于num的排在数组左边,等于num的排在数组中间;

要求:空间复杂度为O(1)    时间复杂度为O(n)

//原荷兰国旗问题是:现有红白蓝三个不同颜色的小球,乱序排列在一起,请重新排列这些小球,使得红白蓝三色的同颜色的球在一起。这个问题之所以叫荷兰国旗问题,是因为我们可以将红白蓝三色小球想象成条状物,有序排列后正好组成荷兰国旗。

可得知此二问题为同等道理,不同的体现;

我们可以想到最最清晰思路为:直接将此数组按升序排列自然可以达到题目要求。

现我有此想法可描述为:

<1>:遍历数组,并计算大于num的个数为righ,小于num的个数为left,等于num的数字个数为mid;

<2>:遍历数组,若数字小于num便与数组从a[0]到a[left]的数交换;同理交换等于num,大于num的数;

代码实现为:

#include <stdio.h>
int main()
{
int a[8] = {3, 2, 5, 8, 6, 4, 7, 9};
int i, left=0, mid=0, right=0, j;
int num = 5;
for (i = 0; i <= 7; i++)
{
if (a[i] < num)
left++;
if (a[i] == num)
mid++;
if (a[i] > num)
right++;
}
printf("%d %d %d ",left,mid,right);
printf("\n");
for (i = 0, j = 0; i <= 7 ; i++)
{
if (a[i] < num)
{
int t = a[i];
a[i] = a[j];
a[j] = t;
j++;
}
}
for (i = left, j = left; i <= 7; i++)
{
if (a[i] == num)
{
int t = a[i];
a[i] = a[j];
a[j] = t;
j++;
}
}
for (i = 0; i <= 7; i++)
printf("%d ", a[i]);
}

此代码显然可以优化,下次将分享优化后的代码。

阅读更多

没有更多推荐了,返回首页