关于正负整数数组的一个算法

题目:

一个未排序整数数组,有正负数,重新排列使负数排在正数前面,并且要求不改变原来的正负数之间相对顺序 比如: input: 1,7,-5,9,-12,15 ans: -5,-12,1,7,9,15 要求时间复杂度O(N),空间O(1) 。

这个题目的难点在于对复杂度和空间要求十分苛刻,思考了很长时间,觉得只能用一些非常规的方法来解决。

思路是让一个数组的值来包含更多的信息。

对于一个数组arr来说,他的长度为length,假设length<100, 那么把数组的值乘以100,这样就把数组的值扩展了两位,然后用后两位来表示下标的值。就本题来说,遍历一遍,可以获得负数的个数,根据题目的要求,当知道了负数的个数,则每个数组值在结果里的位置也就确定了,可以把这个值存在扩展的位置上。java实现的代码如下:

public class HandleArr {

public static void main(String[] args){
int[] arr={1,12,8,-6,-55,36,77,-99};
for(int i : arr){
System.out.println(i);
}
System.out.println();
System.out.println();
new HandleArr().handle(arr);
for(int i : arr){
System.out.println(i);
}

}

public int[] handle(int[] arr){
if(arr==null){
return null;
}
int n=this.getLength(arr.length);

int exIndex=1;//需要扩展的长度
for(int i=0;i<n;i++){
exIndex*=10;
}

int nLength=0;//记录负数的个数

for(int i=0;i<arr.length;i++){
if(arr[i]<0)nLength++;
}
int nIndex=0;//记录负数的下标
int pIndex=nLength;//记录正数的下标

//把每个数组值最终的位置存放到扩展中
for(int i=0;i<arr.length;i++){
if(arr[i]<0){
arr[i]=arr[i]*exIndex-nIndex;
nIndex++;
}else{
arr[i]=arr[i]*exIndex+pIndex;
pIndex++;
}
}

int count=0;

/*
*把每个数组值放到正确的位置
*这个复杂度不会超过2n,证明从略
*/
for(;count<arr.length;){
int index=Math.abs(arr[count]%exIndex);
if(index==count){
count++;
}else{
int temp=arr[count];
arr[count]=arr[index];
arr[index]=temp;
}
}
for(int i=0;i<arr.length;i++){
arr[i]/=exIndex;
}


return arr;
}

//用来获得数组长度的位数,这里有点疑问,就是复杂度怎么看
private int getLength(int n){
int length=1;
while(n/10>0){
length++;
}
return length;
}


}

最后有个疑问,就是计算数组长度的位数,这个复杂度是多少。

阅读更多
想对作者说点什么? 我来说一句

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

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭