大家参考一下,时间O(N)?和空间O(1)。
基本思想是借鉴in-place merge sort:
只做一次扫描,
1,记录第一次出现正数的位置,寻找第二次出现正数的位置或结尾,
2,对两个位置中间进行手摇算法反转
3,重复1,2直到结尾
示例:1,7,-5,9,-12,15
int front=0;
int last =0;
while (last<NUM/*总数*/)
{
一,当front==0,last==3时,反转1,7,-5,于是为-5,1,7,9,-12,15。这时置front=1,last还是3。
二,再次进入,当front==1,last==5(也可以是结尾,有可能最后一个是负数),反转1,7,9,-12,于是为-5,-12,1,7,9,15。这时置front=2,last还是5。
三,ok,last结束,退出循环。
last++;
}
为什么对时间O(N)打问号,主要是这里要考虑,反转存在正数序列(或负数,也可以以负数为反转对象)变大的问题。下回有时间可以再思考一下。
另:消除这种正数序列变大的问题,有一种思想就是分块,把序列分成sqrt(N)块(当然这里也要考虑到正负颗粒的问题),这样整体时间复杂度应该可以控制在O(N)了。
汗~有点晚了-_-。睡了。
基本思想是借鉴in-place merge sort:
只做一次扫描,
1,记录第一次出现正数的位置,寻找第二次出现正数的位置或结尾,
2,对两个位置中间进行手摇算法反转
3,重复1,2直到结尾
示例:1,7,-5,9,-12,15
int front=0;
int last =0;
while (last<NUM/*总数*/)
{
一,当front==0,last==3时,反转1,7,-5,于是为-5,1,7,9,-12,15。这时置front=1,last还是3。
二,再次进入,当front==1,last==5(也可以是结尾,有可能最后一个是负数),反转1,7,9,-12,于是为-5,-12,1,7,9,15。这时置front=2,last还是5。
三,ok,last结束,退出循环。
last++;
}
为什么对时间O(N)打问号,主要是这里要考虑,反转存在正数序列(或负数,也可以以负数为反转对象)变大的问题。下回有时间可以再思考一下。
另:消除这种正数序列变大的问题,有一种思想就是分块,把序列分成sqrt(N)块(当然这里也要考虑到正负颗粒的问题),这样整体时间复杂度应该可以控制在O(N)了。
汗~有点晚了-_-。睡了。