解1:调整数组顺序使奇数位于偶数前面 I

🚩传送门:牛客题目

题目

输入一个长度为 🍗调整数组顺序使奇数位于偶数前面合集 - 图1 整数数组,数组里面可能含有相同的元素,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前面部分,所有的偶数位于数组的后面部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变,但是时间复杂度和空间复杂度必须如下要求。

要求:时间复杂度 🍗调整数组顺序使奇数位于偶数前面合集 - 图2,空间复杂度 🍗调整数组顺序使奇数位于偶数前面合集 - 图3

解题思路:模拟

将原数组的奇数偶数按顺序拷贝下来

复杂度分析

时间复杂度:🍗调整数组顺序使奇数位于偶数前面合集 - 图4,其中 🍗调整数组顺序使奇数位于偶数前面合集 - 图5 为数组的长度。每个元素只会被遍历 2 次。

空间复杂度:🍗调整数组顺序使奇数位于偶数前面合集 - 图6,我们只需新建一个长度为🍗调整数组顺序使奇数位于偶数前面合集 - 图7的数组。

我的代码
  1. public class Solution {
  2. public int[] reOrderArray(int[] array) {
  3. int n = array.length;
  4. int[] arr = new int[n];
  5. int j = 0;
  6. for (int i = 0; i < n; i++) {
  7. if ((array[i] & 1) == 1)
  8. arr[j++] = array[i];
  9. }
  10. for (int i = 0; i < n; i++) {
  11. if ((array[i] & 1) == 0)
  12. arr[j++] = array[i];
  13. }
  14. return arr;
  15. }
  16. }

解2:调整数组顺序使奇数位于偶数前面 II

🚩传送门:牛客题目
力扣题目

题目

输入一个长度为 🍗调整数组顺序使奇数位于偶数前面合集 - 图8 整数数组,数组里面可能含有相同的元素,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前面部分,所有的偶数位于数组的后面部分,对奇数和奇数,偶数和偶数之间的相对位置不做要求,但是时间复杂度和空间复杂度必须如下要求。

要求:时间复杂度 🍗调整数组顺序使奇数位于偶数前面合集 - 图9,空间复杂度 🍗调整数组顺序使奇数位于偶数前面合集 - 图10

示例:

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

解题思路:双指针 I

使用 🍗调整数组顺序使奇数位于偶数前面合集 - 图11🍗调整数组顺序使奇数位于偶数前面合集 - 图12双指针,其中:

  1. 🍗调整数组顺序使奇数位于偶数前面合集 - 图13 区间都是奇数,为已处理部分
  2. 🍗调整数组顺序使奇数位于偶数前面合集 - 图14 区间都是偶数部分
  3. 🍗调整数组顺序使奇数位于偶数前面合集 - 图15区间都是未处理部分

指针 🍗调整数组顺序使奇数位于偶数前面合集 - 图16从前向后遍历,遇到偶数不管,遇到奇数,如果🍗调整数组顺序使奇数位于偶数前面合集 - 图17🍗调整数组顺序使奇数位于偶数前面合集 - 图18指针不等则互换

复杂度分析

时间复杂度:🍗调整数组顺序使奇数位于偶数前面合集 - 图19,其中 🍗调整数组顺序使奇数位于偶数前面合集 - 图20 为数组的长度。每个元素只会被遍历一次。

空间复杂度:🍗调整数组顺序使奇数位于偶数前面合集 - 图21,我们只需常数空间。

我的代码
  1. public class Solution {
  2. public void swap(int[] array, int i, int j) {
  3. int temp = array[i];
  4. array[i] = array[j];
  5. array[j] = temp;
  6. }
  7. public int[] reOrderArrayTwo(int[] array) {
  8. int i = 0;
  9. for (int j = 0; j < array.length; j++) {
  10. // 判断是否是奇数,奇数互换、偶数不管
  11. if ((array[j] & 1) == 1) {
  12. if (i == j) {
  13. i++; // i,j相同没必要互换,i下移就好
  14. } else {
  15. swap(array, i++, j);
  16. }
  17. }
  18. }
  19. return array;
  20. }
  21. }

解题思路:双指针 II

考虑定义双指针 🍗调整数组顺序使奇数位于偶数前面合集 - 图22 , 🍗调整数组顺序使奇数位于偶数前面合集 - 图23 分列数组左右两端,循环执行:

  • 指针🍗调整数组顺序使奇数位于偶数前面合集 - 图24 从左向右寻找偶数;
  • 指针🍗调整数组顺序使奇数位于偶数前面合集 - 图25从右向左寻找奇数;
  • 偶数 🍗调整数组顺序使奇数位于偶数前面合集 - 图26奇数 🍗调整数组顺序使奇数位于偶数前面合集 - 图27 交换。

可始终保证: 指针 🍗调整数组顺序使奇数位于偶数前面合集 - 图28 ,左边都是奇数,指针🍗调整数组顺序使奇数位于偶数前面合集 - 图29右边都是偶数 。
🍗调整数组顺序使奇数位于偶数前面合集 - 图30

复杂度分析

时间复杂度:🍗调整数组顺序使奇数位于偶数前面合集 - 图31,其中 🍗调整数组顺序使奇数位于偶数前面合集 - 图32 为数组的长度。每个元素只会被遍历一次。

空间复杂度:🍗调整数组顺序使奇数位于偶数前面合集 - 图33,我们只需常数空间。

我的代码
  1. class Solution {
  2. public int[] exchange(int[] nums) {
  3. int i = 0;
  4. int j = nums.length - 1;
  5. int tmp;
  6. while(i < j) {
  7. while(i < j && (nums[i] & 1) == 1) i++;
  8. while(i < j && (nums[j] & 1) == 0) j--;
  9. tmp = nums[i];
  10. nums[i] = nums[j];
  11. nums[j] = tmp;
  12. }
  13. return nums;
  14. }
  15. }