调整数组顺序使奇数位于偶数前面( python实现 )
一、题目描述
题目:调整数组顺序使奇数位于偶数前面
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
二、解题思路
首先来思考一种简单的方式,将该数组从头到尾遍历。当遍历到一个偶数时,将其取出保存到临时变量中,然后从该偶数所在位置开始,依次将其后的所有数字向前挪动一位。挪完之后,在数组的末尾有一个空位,将取出来的偶数放入这个空位。
不难看出,这种方式实现的算法时间复杂度为 O ( n 2 ) O(n^{2}) O(n2),不尽人意,考虑是否存在线性时间复杂度 O ( n ) O(n) O(n) 的方式。
这道题目的要求,是将奇数放在数组的前半部分,偶数放在数组的后半部分。因此,我们在扫描这个数组的过程中,只要发现奇数在偶数的后面,直接交换它们的顺序即可。这样就省去了挪位的操作,将算法效率降低到线性时间复杂度。
具体操作如下(可结合下图理解):
Step1 :定义两个指针,初始化指针时,一个指针 ( pLeft ) 指向数组的一端,另外一指针 ( pRight ) 指向数组的另外一端。(在Python中,用下标索引实现指针操作)
Step2 :首先判断 pLeft 所指向的数字是否指向偶数,若不是,则循环执行 pLeft = pLeft+1(即向右移动一位),若是,则停下来;
Step3 :接着判断 pRight 是否指向奇数,若不是,则循环执行 pRight = pRight-1( 即向左移动一位),若是也停下来;
Step4 :当两个指针都停下来,然后交换两个指针位置的数字。
Step5:当满足 pLeft < pRight 条件时,循环执行 Step2 - Step4;不满足该条件时,结束此循环。
当然,以上所有循环的执行都必须满足 pLeft < pRight 条件,可参考代码理解。
三、代码实现
def ReorderOddEven(myList):
if len(myList)==0:
return
pLeft = 0
pRight = len(myList)-1
while pLeft < pRight:
while pLeft < pRight and myList[pLeft] & 0x1 == 1:
pLeft = pLeft+1
while pLeft < pRight and myList[pRight] & 0x1 ==0:
pRight = pRight-1
if pLeft < pRight:
myList[pLeft],myList[pRight] = myList[pRight],myList[pLeft]
return myList
>>> myList = [2,4,5,8,9,6,4,5,8,4,1,2,3,5,7,8,5,6,9,4]
>>> ReorderOddEven(myList)
Out:
[9, 5, 5, 7, 9, 5, 3, 5, 1, 4, 8, 2, 4, 6, 8, 8, 4, 6, 2, 4]