根据某些条件移动元素也是一类常见的题目,例如排序本身就是在移动元素,这里看一个奇偶移动的问题。
LeetCode905. 按奇偶排序数组https://leetcode.cn/problems/sort-array-by-parity/
LeetCode905. 按奇偶排序数组
给你一个整数数组 nums
,将 nums
中的的所有偶数元素移动到数组的前面,后跟所有奇数元素。
返回满足此条件的 任一数组 作为答案。
示例 1:
输入:nums = [3,1,2,4] 输出:[2,4,3,1] 解释:[4,2,3,1]、[2,4,1,3] 和 [4,2,1,3] 也会被视作正确答案。
示例 2:
输入:nums = [0] 输出:[0]
一)方法一:暴力解法
思路:申请一个新的数组,第一遍查找并将所有的偶数复制到新数组的前部分,第二遍查找并复制所有的奇数到数组后部分。
这个比较容易想到,但是要申请新的空间,有没有空间复杂度为O(1)的办法呢~
二)方法二:对撞双指针
思路:和上次删除数组元素中的那题思路一模一样(在上一篇文章),定义left和right指针,
两指针向中间靠拢,核心思想是从右侧找到偶数来顶替左侧的奇数。
上代码~
class Solution {
public int[] sortArrayByParity(int[] nums) {
int right = nums.length - 1; // 右指针初始指向数组最后一个元素
int left = 0; // 左指针初始指向数组第一个元素
while (left <= right) { // 使用 while 循环来处理元素交换
// 如果左指针指向的元素为奇数,且右指针指向的元素为偶数
if (nums[left] % 2 != 0 && nums[right] % 2 == 0) {
// 交换左指针和右指针指向的元素
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
}
// 如果左指针指向的元素为偶数,将左指针后移
if (nums[left] % 2 == 0) left++;
// 如果右指针指向的元素为奇数,将右指针前移
if (nums[right] % 2 != 0) right--;
}
// 返回修改后的数组
return nums;
}
}
结合上一期LeetCode27方法二,对撞双指针,理解那道题,再来做这道题,就会很轻松。