题⽬描述
输⼊⼀个⻓度为 n 整数数组,数组⾥⾯不含有相同的元素,实现⼀个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前⾯部分,所有的偶数位于数组的后⾯部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
示例1 输⼊:[1,2,3,4] 返回值:[1,3,2,4]
示例2 输⼊:[2,4,6,5,7] 返回值:[5,7,2,4,6]
示例3 输⼊:[1,3,5,6,7] 返回值:[1,3,5,7,6]
思路及解答
空间换时间(辅助数组)
通过创建两个临时数组分别存储奇数和偶数,然后合并它们。这种方法简单易懂,但需要额外的空间。
新建⼀个数组, copy ⼀份,先计算出奇数的个数,也就是能够知道第⼀个偶数应该放在数组的哪⼀个位置,然后再遍历⼀次,依次放到对应的位置即可。
时间复杂度:O(n),需要遍历数组两次(分离和合并各一次)
空间复杂度:O(n),需要额外的两个列表存储所有元素
双指针原地排序(类似插入排序)
使用类似插入排序的思想,维护一个"已排序奇数"的边界,当遇到奇数时,将其插入到边界位置并移动边界。这种方法不需要额外空间,但时间复杂度较高。
时间复杂度:O(n²),最坏情况下每次奇数都需要移动大量元素
空间复杂度:O(1),原地排序,不需要额外空间
两次遍历填充法
通过两次遍历数组,第一次填充所有奇数,第二次填充所有偶数。这种方法结合了方法一的思路,但使用固定大小的结果数组
时间复杂度:O(n),需要遍历数组两次
空间复杂度:O(n),需要一个结果数组
稳定的双指针交换法
使用两个指针,一个从前往后找偶数,一个从后往前找奇数,然后交换它们的位置。这种方法需要特别注意保持相对顺序
时间复杂度:O(n²),最坏情况下需要移动大量元素
空间复杂度:O(1),原地操作
优化的双指针法(保持稳定性)
结合双指针和插入排序的思想,维护奇数指针和遍历指针,当遇到奇数时,将其插入到奇数指针位置并移动指针。
时间复杂度:O(n²),最坏情况下需要移动大量元素
空间复杂度:O(1),原地操作
方法对比与总结
方法时间复杂度空间复杂度优点缺点辅助数组法O(n)O(n)实现简单,顺序有保证空间开销大双指针原地排序O(n²)O(1)空间效率高时间效率低两次遍历填充法O(n)O(n)时间效率高空间开销中等稳定双指针交换法O(n²)O(1)空间效率高实现复杂,时间效率低优化双指针法O(n²)O(1)空间效率高,顺序保证好时间效率低