21:调整数组顺序使奇数位位于偶数位前面(剑指offer第2版Python)

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值