不改变正负数之间相对顺序重新排列数组

数组排序使得数组负数在正数左边按照原来的顺序 假设一整型数组存在若干正数和负数,现在通过某种算法使得该数组的所有负数在正数的左边,保证负数件和正数间元素相对位置不变。时空复杂度要求分别为:o(n),o(1) 例如 -3 4 2 -1 7 3 -5 排序后 -3 -1 -5 4 2 7 3 算法思想:从前往后遍历,记录第一个正数的位置,如果遇到负数就将负数插入到正数前面。 Go算法如下: funcsort... 阅读详情
不改变正负数之间相对顺序重新排列数组
一个未排序整数数组,有正负数,重新排列使负数排在正数前面,并且要求不改变原来的正负数之间相对顺序。
比如: input: 1,7,-5,9,-12,15 ,ans: -5,-12,1,7,9,15 。且要求时间复杂度O(N),空间O(1)


说一个O(n)时间,O(1)空间的方法。
 
开一个Int[32]数组,可以在O(n)的时间内对原数组进行分块,块的大小为32。例如:
 
-1 -9 1 8 9 4 - 2 3 5 6 7 -8 2 1 -3 -7 -11 -1 3 4
用一个长度为4的数组,分为长度为4的块,归并过程大概是这样的(x表示空着的位置):
x x x x
-1 -9 1 8 9 4 -2 3 5 6 7 -8 2 1 -3 -7 -11 -1 3 4
=>
1 8 9 4
-1 -9 x x x x -2 3 5 6 7 -8 2 1 -3 -7 -11 -1 3 4
=>
-1 -9 x x
1 8 9 4 x x -2 3 5 6 7 -8 2 1 -3 -7 -11 -1 3 4
=>
-1 -9 -2 x
1 8 9 4 3 5 6 7 x x x -8 2 1 -3 -7 -11 -1 3 4
=>
x x x x
1 8 9 4 3 5 6 7 -1 -9 -2 -8 2 1 -3 -7 -11 -1 3 4
=>
-3 -7 -11 -1
1 8 9 4 3 5 6 7 -1 -9 -2 -8 2 1 x x x x 3 4
=>
2 1 x x
1 8 9 4 3 5 6 7 -1 -9 -2 -8 -3 -7 -11 -1 x x 3 4
=>
x x x x
1 8 9 4 3 5 6 7 -1 -9 -2 -8 -3 -7 -11 -1 2 1 3 4
 
每个块里只有正数或负数(除了最后1个或2个块),不存在正负交替的情况。在这个过程中记录一下正负块的个数(上面的例子中,正数3个块,负数2个块)。
 
然后我们发现,既然每个块里不是正数就是负数,那么这32个数其实只需要1个标志来标明是正数还是负数,我们保留这32个数中第一个数的符号,剩下的31个数,每个数可以为我们提供1Bit的信息量,我们还可以用来保留其他信息。在此我们用来存储这个块儿的最终位置信息。有了这部分信息,我们可以利用类似原地归并的方法,在O(n)时间内,完成对块儿的排序。
 
以分好块的1 8 9 4 3 5 6 7 -1 -9 -2 -8 -3 -7 -11 -1 2 1 3 4为例,
 
总共有2个负数块儿,因此1 8 9 4是最终排第3的块,3 5 6 7 第4 | -1 -9 -2 -8第1 |-3 -7 -11 -1 第2| 2 1 3 4第5
 
我们用0 - 4的编号表示第1至第5
 
1 8 9 4 对应2,二进制表示为10,填满3位就是010,把每个块的第1位保持不动,后面用来记录位置,1 8 9 4变为了1 8 -9 4。同理3 5 6 7对应第3个块,3的二进制表示为011,3 5 6 7变为3 5 -6 -7
 
最后再用O(n)的时间处理一下最后的两个块,方法类似于字符串的翻转。这样的话总的时间为O(n),空间主要是那个Int[32]辅助数组,用在最初分块那部分,其实再小一些也可以,那样看起来更像O(1),但逻辑要复杂很多,在这里不细说了。

改变正负数之间相对顺序重新排列数组(时间O(N),空间O(1)) 改变正负数之间相对顺序重新排列数组(时间O(N),空间O(1)) 原帖位置:http://blog.csdn.net/v_july_v/article/details/7329314 问题:请看原帖 原帖解决方法评论: 区间翻转的最优解决方法是采用二分法进行区间翻转,因此其最差时间复杂度为O(NlogN),认为该思路无法解决该问题。 例如:   (+-)(+-)(+-)( 阅读详情

相关推荐

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

参考http://blog.csdn.net/v_july_v/article/details/7329314 题目如下:     一个未排序整数数组,有正负数重新排列使负数排在正数前面,并要求改变原来的正负数之间相对顺序。      比如: input: 1,7,-5,9,-12,15 ,ans: -5,-12,1,7,9,15 。要求时间复杂度O(N),空间O(1) 。

雨夜聆风的专栏 2533

java算法-数组正负数排序

问题: 一个整型数组,其中的数值有正有负,先需要将负数调整到左边,正数调整到右边。 思路: 问题描述负数在左,正数在右。那么我们就可以从前后同时开始扫描,前面扫描到正数,就交换到后面扫描到负数的位置。代码如下: public static void main(String[] args) throws IOException { int []array = {1, 3, -8, -9, 6, 9, 10, -2, 4, -5, 91, 55, -66, -33, 7};

u010825190的博客 934

数组里的负数排在数组的前面,正数排在数组的后面。但改变原先负数和正数的排列顺序

题目描述:将数组里的负数排在数组的前面,正数排在数组的后面。但改变原先负数和正数的排列顺序。例:input: -5,2,-3, 4,-8,-9, 1, 3,-10;output: -5, -3, -8, -9, -10, 2, 4, 1, 3。 算法描述: ①设定两个计数器begin、end,其中begin始终指向数组中的第一个负数,end始终指向位于begin之后的第一个正数。然后把b

tianmo2010的专栏 8111

计数排序(java)

一、算法思想 针对整数序列(包括负数),创建待排序数组最大值+1的辅助数组, 根据待排序数组值找到对应辅助数组下标,让对应下标值+1,最终 扫描辅助数组获得排序结果。 解决负数问题 同整=正数一样开辟一个辅助空间,空间大小为最小数(负数)(兼容正数)的绝对值+1,在计数时判断正负进入同的辅助数组,其中负数辅助数组用绝对值代替,在输出时,先从大到小输出负数辅助数组(切记*-1)在输出正数辅助数组算法优势: 时间复杂度低O(n); 算法劣势: 对于稀疏数列,浪费空间; 二、代码实现 publ

Zc9741的博客 917

改变正负数相对顺序重新排列数组

class Program { const int MaxSize = 1000; static void Main(string[] args) { int PosiNum = 0,PosiDone=0; int NegaNum = 0,NegaDone=0; i

newbie724的专栏 847

改变正负数之间相对顺序重新排列数组

一个未排序整数数组,有正负数重新排列使负数排在正数前面,并要求改变原来的正负数之间相对顺序。 比如: input: 1,7,-5,9,-12,15 ,ans: -5,-12,1,7,9,15 。 如果题目要求要保持相对顺序不变,那么就有技术含量了,那么就要整块整块的移动,从后往前扫描,遇到负数,开始记录负数区间,然后遇到正数,记录前面的正数区间,然后把整个负数区间与前面的正数区间进行交换

1466

一个未排序整数数组,有正负数重新排列使负数排在正数前面,并要求改变原来的正负数之间相对顺序。 要求时

貌似wujie 若用保证相对顺序,则代码如下,类似partition,pivot=0 void rearrange(int arr[], int n) { int i = -1,j; for(j = 0; j < n; j++) { if(arr[j] < 0) { i++; sw

stay hungry,stay foolish 2916

第二十七章:改变正负数之间相对顺序重新排列数组

一个未排序整数数组,有正负数重新排列使负数排在正数前面,并要求改变原来的正负数之间相对顺序。 比如: input: 1,7,-5,9,-12,15 ,ans: -5,-12,1,7,9,15 。要求时间复杂度O(N),空间O(1) 。 没有什么很好的方法 #include #include #include using namespace std; vo

王川的私房菜 1340

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

改变正负数之间相对顺序重新排列数组(时间O(N),空间O(1)) 原帖位置:http://blog.csdn.net/v_july_v/article/details/7329314 问题:请看原帖 原帖解决方法评论: 区间翻转的最优解决方法是采用二分法进行区间翻转,因此其最差时间复杂度为O(NlogN),认为该思路无法解决该问题。 例如:   (+-)(+-)(+-)(

chenyujing1234的专栏 1346

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

大概思路: 1,遍历数组,找到最小值,最大值,以及负数元素个数,然后设 s = 最小值绝对值,m = 最大值 + 1,k = 负数元素个数 - 1。 2,遍历数组改变每个元素,设该元素为a, 改变后为 c = a+s + (m+s)*n, 其中,n为该元素在按照题目要求排序后的位置,其实难得到,遍历过程中分别用两个变量保存当前正负元素的排序号,如果当前元素是负数,则第一个变量+1然后付

suiyili的专栏 1090

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

#include using namespace std; void txsort(int* arr, int len) { if (!arr || len == 1) { return; } int negCount = 0; for (int i = 0; i < len; ++i) { if (arr[i] < 0) { negCount++; } } i

Edwards_June的专栏 2621

第二十七章:改变正负数之间相对顺序重新排列数组.时间O(N),空间O(1)

 在这篇文章:九月腾讯,创新工场,淘宝等公司最新面试十三题的第5题(一个未排序整数数组,有正负数重新排列使负数排在正数前面,并要求改变原来的正负数之间相对顺序),自从去年九月收录了此题至今,一直未曾看到令人满意的答案,为何呢?     因为一般达到题目所要求的:时间复杂度O(N),空间O(1),保证原来正负数之间相对位置不变。本编程艺术系列第27章就来阐述这个问题,若有任何漏洞,欢迎...

weixin_33815613的博客 336

(原创)链表实现:改变正负数之间相对顺序重新排列数组,要求时间O(N),空间O(1)——理解错误,作废!!...

刚刚看到July博客里关于一道题目的解法,原文链接:http://blog.csdn.net/v_july_v/article/details/7329314#cpp   重新排列使负数排在正数前面   原题是这样的:   一个未排序整数数组,有正负数重新排列使负数排在正数前面,并要求改变原来的正负数之间相对顺序。比如: input: 1,7,-5,9,-12,15 ,ans: -5,...

weixin_30871701的博客 268

含有正负值的数组C语言排序,一个未排序整数数组,有正负数重新排列使负数排在正数前面,并要求改变原来的正负数之间相对顺序,比如: input: 1,7,-5,9,-12,15 ans: -5,-1...

#include using namespace std;void txsort(int* arr, int len) {if (!arr || len == 1) {return;}int negCount = 0;for (int i = 0; i < len; ++i) {if (arr[i] < 0) {negCount++;}}int swapingId = 0;int fi...

weixin_39732491的博客 1261

102奇偶调序

题目: 输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)。 思路: 利用快排中

dongqing0812的专栏 526
上一篇: 一个数组存放了2n+1个整数,其中有n个数出现了2次,1个数出现了1次,找出出现1次的数是多少?
下一篇: 关于D3D中AGP显存,内存,显存三种内存的解释
DSIslander
博客等级 码龄20年 14粉丝 2原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值