您的位置:首页 > 其它

算法,不改变正负数之间相对顺序重新排列数组.时间O(N),空间O(1)

2012-03-13 20:39 351 查看
大概思路:
1,遍历数组,找到最小值,最大值,以及负数元素个数,然后设 s = 最小值绝对值,m = 最大值 + 1,k = 负数元素个数 - 1。

2,遍历数组,改变每个元素,设该元素为a, 改变后为 c = a+s + (m+s)*n, 其中,n为该元素在按照题目要求排序后的位置,其实不难得到,遍历过程中分别用两个变量保存当前正负元素的排序号,如果当前元素是负数,则第一个变量+1然后付值给n,如果是正数,则第二个变量+1然后付值给n,注意,第一个变量从0开始计数,第二个从k开始计数。

3,再次遍历数组,设每个元素为c,则c对(m+s)取余数后得到b,由于b= a+s => a = b-s,然后 (c -b)/(m+s) 得到n,也就是该元素的排序号,用此排序号进行占位排序,一个替一个一直到最大号。

简单的说如果把数组先变成正数,
A ={-1,8,-2,-3,2,7} , 最大元素 8 设m=8+1=9, -3最小设s=3,都加3=> {2,11,1,0,5,10}=B。

然后是用最大元素11加上1=12,即m+s=9+3=12 作为参数用于改变数组B每个元素,C={2+12*1, 11+12*4(也就是初始数组元素8到最后应该排在第4位), 1+12*2, 0+12*3, 5*12*5, 10*12*6}
初始数组A最大元素8=>m=8+1=9,也就是说m+s=9+3=12大于任何一个数组B中的元素,那么通过构造C中元素c=a+s+(m+s)*n我们不但能够存储原有A中元素a,还可以存储排序后的排号n.
原理等同于那个把整数变成浮点数的方法,但是我这里通过计算还原原来的元素以及排序号,c%(m+s)得到a+s,a可以还原,(c-a-s)/(m+s)得到排序号。

代码如下:

#include <limits>
#include <iostream>

using namespace std;

int main(int argc, char **argv)
{
const size_t size = 6;
int A[size] = {-3,1,8,-2,1,2};

//first step, find min, max

int min = numeric_limits<int>::max();
int max = numeric_limits<int>::min();
//and number of elements which is less than 0
//later used as unsigned elements new position
size_t unsignedCnt = 0;
for(size_t i = 0; i < size; ++i)
{
if(A[i] < min)
min = A[i];
if(A[i] > max)
max = A[i];
if(A[i] < 0)
++unsignedCnt;
}
++max;
if(min < 0)
min = -min;

//signed elements first position
size_t signedCnt = 0;

//new position index
size_t cnt = 0;
for(size_t i = 0; i < size; ++i)
{
//update element to make them greater than 0
//and include a final position in

if(A[i] < 0)
cnt = ++signedCnt;
else
cnt = ++unsignedCnt;

//update element
//cnt starts from 1
A[i] = A[i] + min + (min + max) * cnt;
}

//in-place key index sorting
for(size_t i = 0; i < size; ++i)
{
//if the element already put in right position continue
if(A[i] <= max) continue;
else
{
int
4000
temp = 0;
int prev = A[i];
size_t id = 0;

do{
temp = prev % (max + min);
id = (prev - temp)/(min + max) - 1;
prev = A[id];
A[id] = temp - min;
}while(id != i);

}

}

for(size_t i = 0; i < size; ++i)
{
cout << A[i]<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 include 存储 less c
相关文章推荐