给定一个数组a = {1,2,3,4,5,6,7,8}
我们应该把所有奇数元素(1,3,5,7)放在一起,甚至将元素(2,4,6,8)放在一起,同时保留顺序。
输入:[1,2,3,4,5,6,7,8]。 产出:[1,3,5,7,2,4,6,8]。
更新:(示例2) 例2:[3,54,77,86,45,2,25,100] 输出:[3,77,45,25,54,86,2,100]
限制:O(N)时间复杂度和O(1)空间复杂度。
我的方法: 1.在(快速分区)中分区 问题:订单未保留。 (1,7,3,5,4,6,2,8)-O(N)时间复合体 2.将奇数元素置于合法位置并移动所有其他元素: 问题:每个元素都有O(N),而移位需要另一个O(N)。因此时间复杂度变为O(N ^ 2)
是否存在O(N)时间复合物和O(1)空间复合物解决方案?
答案 0 :(得分:3)
看看你是否可以根据周期推广这些排列解决方案,注意排序的索引是I [] = {0,2,4,6,1,3,5,7},I [1] = 2,I [2] = 4,I [4] = 1,循环结束。 I [3] = 6,I [6] = 5,I [5] = 3,循环结束。这里的问题是如果事先不知道n,那么即使I [i]可以在运行中计算(I [i] =(2 * i< n)?2 * i:(2 * in)| 1;),问题是跟踪已经处理了哪些周期,这可能需要O(n)空间。
对于8个元素,它是两个周期,每个元素3个元素:
0 1 2 3 4 5 6 7
I[] = 0 2 4 6 1 3 5 7
t = a[1] 2
a[1] = a[2] 1 3 3 4 5 6 7 8
a[2] = a[4] 1 3 5 4 5 6 7 8
a[4] = t 1 3 5 4 2 6 7 8
t = a[3] 4
a[3] = a[6] 1 3 5 7 2 6 7 8
a[6] = a[5] 1 3 5 7 2 6 6 8
a[5] = t 1 3 5 7 2 4 6 8
对于12个元素,它只是10个元素的一个周期
0 1 2 3 4 5 6 7 8 9 10 11
I[] = 0 2 4 6 8 10 1 3 5 7 9 11
t = a[ 1] 2
a[ 1] = a[ 2] 1 3 3 4 5 6 7 8 9 10 11 12
a[ 2] = a[ 4] 1 3 5 4 5 6 7 8 9 10 11 12
a[ 4] = a[ 8] 1 3 5 4 9 6 7 8 9 10 11 12
a[ 8] = a[ 5] 1 3 5 4 9 6 7 8 6 10 11 12
a[ 5] = a[10] 1 3 5 4 9 11 7 8 6 10 11 12
a[10] = a[ 9] 1 3 5 4 9 11 7 8 6 10 10 12
a[ 9] = a[ 7] 1 3 5 4 9 11 7 8 6 8 10 12
a[ 7] = a[ 3] 1 3 5 4 9 11 7 4 6 8 10 12
a[ 3] = a[ 6] 1 3 5 7 9 11 7 4 6 8 10 12
a[ 6] = t 1 3 5 7 9 11 2 4 6 8 10 12
对于27个元素,它是3个周期,从[1](19个元素)开始,a [3](6个元素)和a [9](2个元素)。
答案 1 :(得分:1)
这只是部分答案。
这里是数组前半部分的executable pseudocode:
def magic_swap(arr):
mid = len(arr) / 2 + (1 if len(arr) % 2 == 1 else 0)
for i in range(1, mid):
arr[i], arr[i*2] = arr[i*2], arr[i]
下半部分是棘手的部分......如果我弄明白的话,我会更新这个答案。
对于想要解决这个问题的人来说,这里是前几个数组大小的结果:
请注意,当n
为奇数时,大小为n+1
和n
的数组在此方法中始终具有相同的交换顺序。
[1, 2]
[1, 3, 2]
[1, 3, 2, 4]
[1, 3, 5, 4, 2]
[1, 3, 5, 4, 2, 6]
[1, 3, 5, 7, 2, 6, 4]
[1, 3, 5, 7, 2, 6, 4, 8]
[1, 3, 5, 7, 9, 6, 4, 8, 2]
[1, 3, 5, 7, 9, 6, 4, 8, 2, 10]
[1, 3, 5, 7, 9, 11, 4, 8, 2, 10, 6]
[1, 3, 5, 7, 9, 11, 4, 8, 2, 10, 6, 12]
[1, 3, 5, 7, 9, 11, 13, 8, 2, 10, 6, 12, 4]
[1, 3, 5, 7, 9, 11, 13, 8, 2, 10, 6, 12, 4, 14]
[1, 3, 5, 7, 9, 11, 13, 15, 2, 10, 6, 12, 4, 14, 8]
[1, 3, 5, 7, 9, 11, 13, 15, 2, 10, 6, 12, 4, 14, 8, 16]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 10, 6, 12, 4, 14, 8, 16, 2]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 10, 6, 12, 4, 14, 8, 16, 2, 18]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 6, 12, 4, 14, 8, 16, 2, 18, 10]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 6, 12, 4, 14, 8, 16, 2, 18, 10, 20]
答案 2 :(得分:1)
O(1)
和O(n)
限制似乎很难解决问题。
我能找到的最佳匹配是一篇文章Stable minimum space partitioning in linear time,他们提出了一个解决方案,以解决更为普遍的问题。但是,他们的算法很复杂,而且(恕我直言)在实践中不适用。
除非是理论问题,否则我建议分别放宽对O(logN)
和O(NlogN)
的限制,并使用简单的“稳定分区”。算法(已更新):
#inplace reverse block [begin,end) in list l
#O(|end-begin|)
def reverse(l, begin, end):
p = begin
q = end - 1
while p < q:
l[p], l[q] = l[q], l[p]
p = p + 1
q = q - 1
#inplace swaps blocks [begin, mid) and [mid, end) and
#returns a new pivot (dividing point)
#O(|end-begin|)
def swap(l, begin, mid, end):
reverse(l, begin, mid)
reverse(l, mid, end)
reverse(l, begin, end)
return (end - (mid - begin))
#recursive partitioning: partition block [begin, end) into
#even and odd blocks, returns pivot (dividing point)
##O(|end-begin|*log|end-begin|)
def partition(l, begin, end):
if end - begin > 1:
mid = (begin + end) / 2
p = partition(l, begin, mid)
q = partition(l, mid, end)
mid = swap(l, p, mid, q)
return mid
return begin if l[begin] % 2 == 0 else begin + 1
def sort(l):
partition(l, 0, len(l))
return l
print sort([1,2,3,4,5,6,7,8])
更新。对于更新的问题,文章是直接匹配。因此,除非有一些滥用元素数字性质的技巧,否则我们不能解决这个问题。
答案 3 :(得分:-1)
这是一个有效的python程序。不需要额外的空间,只有一个通过阵列 您不需要对数字进行排序或保留原始顺序;把它们放在一起
arr = [1,3,2,4,5,6,3,55,66,77,21,4,5]
iFirst = 0
iLast = len(arr)-1
print arr
while (iFirst < iLast):
while ((arr[iFirst] & 1)==1): # find next even at the front
iFirst += 1
while ((arr[iLast] & 1)==0): # find next odd at the back
iLast -= 1
k = arr[iLast] # exchange them
arr[iLast] = arr[iFirst]
arr[iFirst] = k
iFirst += 1
iLast -= 1
print arr
这是输出。
[1, 3, 2, 4, 5, 6, 3, 55, 66, 77, 21, 4, 5]
[1, 3, 5, 21, 5, 77, 3, 66, 55, 6, 4, 4, 2]