1、题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
2、书上的解法(相对位置改变)
一个类似于快排的方法, 只是简单的满足了奇数在前,偶数在后, 奇数的顺序发生了改变
# -*- coding:utf-8 -*-
class Solution:
def reOrderArray(self, array):
if len(array) < 1:
return
elif len(array) == 1:
return array
front = 0
rear = len(array)-1
while front <= rear:
# 向后移动front指针,直到他指向偶数
while array[front] & 0x1 == 1:
front += 1
# 向前移动rear指针,直到他指向奇数
while array[rear] & 0x1 == 0:
rear -= 1
array[front], array[rear] = array[rear], array[front]
#注意多交换了一次,要再换回来
array[front], array[rear] = array[rear], array[front]
return array
S = Solution()
print(S.reOrderArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]))
输出结果(原相对顺序发生了改变)
[1, 13, 3, 11, 5, 9, 7, 8, 6, 10, 4, 12, 2]
3、牛客网通过解法(相对位置不变)
牛客网附加条件:
保证奇数和奇数,偶数和偶数之间的相对位置不变。
思路:
由于要求相对位置不变,所以以上两种方法不能使用了。网络上对于附加条件的解决方案,没有太好的办法。
一类是采用稳定的排序,例如冒泡,归并。
二是开辟长度为n的数组,遍历原数组,依次把奇数偶数放入新数组,最后将新数组赋值给原数组。时间空间复杂度都没有优化。
要求结果
[1, 3, 5, 7, 9, 11, 13, 2, 4, 6, 8, 10, 12]
3.1、稳定排序(冒泡)
# -*- coding:utf-8 -*-
class Solution:
def reOrderArray(self, array):
k = 0 # 记录奇数偶数分割处
for i in range(len(array)):
if array[i] & 0x01 == 1: # 找到奇数
j = i
while j > k:
array[j], array[j-1] = array[j-1], array[j] # 奇数向前冒泡,放到已归位的奇数后面
j -= 1
k += 1
return array
S = Solution()
print(S.reOrderArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]))
3.2、开辟额外空间
# -*- coding:utf-8 -*-
class Solution:
# 奇数在前,偶数在后
def reOrderArray(self, array):
if len(array) < 1:
return []
if len(array) == 1:
return array
arrayOdd = []
arrayEven = []
for num in array:
if num & 0x1:
arrayOdd.append(num)
else:
arrayEven.append(num)
return arrayOdd+arrayEven
def reOrderArray2(self, array):
left = [x for x in array if x & 1]
right = [x for x in array if not x & 1]
return left + right