面试题21.调整数组的顺序使奇数位于偶数前面

本文介绍了一种简单有效的算法,用于将整数数组中的奇数和偶数进行分离,使得所有奇数位于数组的前半部分,所有偶数位于后半部分。通过使用双指针技术,该算法在原地实现了这一目标,无需额外的空间复杂度。

题目:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
示例:

输入:nums = [1,2,3,4]
输出:[1,3,2,4] 
注:[3,1,2,4] 也是正确的答案之一。

思路:
这道题思路很简单,用双指针,指针i从数组头出发,指针j从数组尾出发,当i遇到奇数时往后走,遇到偶数停下,当j遇到偶数时往前走,遇到奇数时停下,都停下时交换两个数,直到两指针相遇。

  • 注:可以用(nums[i] & 1) == 1)判断是否是奇数,因为奇数的二进制表示最后一位一定为1,20=12^{0}=120=1,同理,可以判断偶数。

代码:

class Solution {
    public int[] exchange(int[] nums) {
        int i = 0, j = nums.length - 1;
        while (i < j) {
            while (i < j && ((nums[i] & 1) == 1)) i++;
            while (i < j && ((nums[j] & 1) == 0)) j--;
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
        }
        return nums;
    }
}
### 调整数组顺序使奇数位于偶数前面 设计一个高效的算法将整数数组中的奇数调整偶数前面,是一个常见的面试题。这类问题的目标是通过调整数组顺序,使所有奇数出现在所有偶数之前。在设计算法时,需要考虑时间复杂度、空间复杂度以及奇数偶数之间的相对顺序是否需要保持稳定。 #### 方法一:使用额外空间 这种方法通过遍历原始数组,分别将奇数偶数存储到两个不同的数组中,最后将两个数组合并即可得到所需结果。 ##### 步骤: 1. 遍历原始数组,将所有奇数存入一个数组中。 2. 再次遍历原始数组,将所有偶数存入另一个数组中。 3. 将两个数组合并,得到最终结果。 ##### 代码实现: ```python def reorder_array(nums): odd = [] even = [] for num in nums: if num % 2 == 1: odd.append(num) else: even.append(num) return odd + even ``` 这种方法的时间复杂度为 O(n),空间复杂度为 O(n)。虽然实现简单,但由于使用了额外的空间,可能不适合某些对空间敏感的场景。 #### 方法二:原地调整 为了减少空间复杂度,可以采用原地调整的方法。这种方法通过双指针的方式,在数组内部进行元素交换,从而实现奇数前移、偶数后移的效果。 ##### 步骤: 1. 初始化两个指针,一个从数组头部开始(`i`),另一个从数组尾部开始(`j`)。 2. `i` 指针向后移动,直到找到一个偶数。 3. `j` 指针向前移动,直到找到一个奇数。 4. 如果 `i` 和 `j` 指针未相遇,则交换这两个元素。 5. 重复上述步骤,直到 `i` 和 `j` 相遇。 ##### 代码实现: ```python def reorder_array_in_place(nums): i, j = 0, len(nums) - 1 while i < j: while i < j and nums[i] % 2 == 1: i += 1 while i < j and nums[j] % 2 == 0: j -= 1 if i < j: nums[i], nums[j] = nums[j], nums[i] return nums ``` 这种方法的时间复杂度为 O(n),空间复杂度为 O(1),适合在空间受限的环境中使用。此外,这种方法并不保证奇数偶数的相对顺序不变,如果需要保持顺序,则需要采用其他策略。 #### 方法三:保持奇偶顺序的稳定性 如果题目要求奇数偶数的相对顺序不能改变,可以采用冒泡排序的思想,通过相邻元素的交换,将偶数逐步后移,奇数前移。 ##### 代码实现: ```python def reorder_array_stable(nums): n = len(nums) for i in range(n): for j in range(n - 1): if nums[j] % 2 == 0 and nums[j + 1] % 2 == 1: nums[j], nums[j + 1] = nums[j + 1], nums[j] return nums ``` 这种方法的时间复杂度为 O(n²),空间复杂度为 O(1)。虽然效率较低,但可以保持奇数偶数的相对顺序不变。 #### 比较与总结 - **使用额外空间**:时间复杂度 O(n),空间复杂度 O(n),实现简单,但占用额外内存。 - **原地调整**:时间复杂度 O(n),空间复杂度 O(1),效率高,但奇偶顺序可能改变。 - **保持奇偶顺序**:时间复杂度 O(n²),空间复杂度 O(1),保证顺序稳定,但效率较低。 根据具体需求,可以选择适合的算法。如果追求效率,推荐使用原地调整的方法;如果要求顺序稳定,可以采用冒泡排序思想;如果内存充足且不要求顺序稳定,使用额外空间的方法是最简单的。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值