「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战」。
题目描述:
905. 按奇偶排序数组 - 力扣(LeetCode) (leetcode-cn.com)
给定一个非负整数数组 A,返回一个数组,在该数组中, A 的所有偶数元素之后跟着所有奇数元素。
你可以返回满足此条件的任何数组作为答案。
示例一
输入: [3,1,2,4]
输出: [2,4,3,1]
输出 [4,2,3,1],[2,4,1,3] 和 [4,2,1,3] 也会被接受。
提示:
1 <= A.length <= 50000 <= A[i] <= 5000
思路分析
遍历
我们可以定义2个指针,遍历两遍数组,第一遍输出偶数,第二遍输出奇数。
AC代码
class Solution {
fun sortArrayByParity(nums: IntArray): IntArray {
var ans = IntArray(nums.size)
var left =0
var right = nums.size -1
nums.forEach{it ->
if(it % 2 == 0){
ans[left++] = it
}else{
ans[right--] = it
}
}
return ans
}
}
双指针原地算法
定义 i, j 分别为第一个和最后一个索引,确保 num[0], nums[1], nums[2], ..., nums[i - 1] 均为偶数。则循环结束的条件为 i < j。
考虑对于 (isEven(nums[i]), isEven(nums[j])) 的四种情况:
(true, false),则满足条件, i++ 且 j--
(false, true),则需要交换两个元素,然后 i++ 且 j--
(true, true),进行 i++
(false, false),进行 j--
通过这四种情况控制循环变量 i, j,最终 nums 变为按照偶奇排列的数组。
AC代码
class Solution {
fun sortArrayByParity(nums: IntArray): IntArray {
var numsCopy = nums.copyOf()
var i = 0
var j = numsCopy.size - 1
while(i < j) {
if(!isEven(numsCopy[i]) && isEven(numsCopy[j])) {
var temp = numsCopy[i]
numsCopy[i] = numsCopy[j]
numsCopy[j] = temp
}
if(isEven(numsCopy[i])) {
i++
}
if(!isEven(numsCopy[j])) {
j--
}
}
return numsCopy
}
fun isEven(num:Int) :Boolean {
return num % 2 == 0
}
}
总结
虽然简单,但是原地算法值得好好研究下。
参考
905. 按奇偶排序数组 题解 - 力扣(LeetCode) (leetcode-cn.com)