LeetCode905: 给定一个非负整数数组 A,返回一个数组,在该数组中, A 的所有偶数元素之后跟着所有奇数元素。
你可以返回满足此条件的任何数组作为答案。
示例:
输入:[3,1,2,4]
输出:[2,4,3,1]
输出 [4,2,3,1],[2,4,1,3] 和 [4,2,1,3] 也会被接受。
问题分类:数组问题;前后排序归类;
问题分析:数组问题一般都需要用到双指针(快慢指针,首尾指针等)。题目要求偶数在前,奇数在后。所以可以对数组进行遍历,然后判断是奇数还是偶数,进行相应的位置调换。
解决方案:(1)首尾指针:从第一个元素开始遍历,如果是奇数,再判断尾指针所指是否为奇数,如果尾指针所指也是奇数,尾指针前移,直到遇到偶数,然后进行调换;如果首指针所指是偶数,首指针前移,开始下一轮判断。循环终止条件为前后指针相遇或首指针小于尾指针。
时间:O(N)
空间:O(1);
(2)直接插入:新建一个数组,再对原数组进行遍历。如果为奇数,将其放入新数组后面,尾指针前移,如果是偶数,将其放入新数组前面,首指针后移。反复操作,直到循环结束。
时间:O(N)
空间: O(N)
/**
-
Note: The returned array must be malloced, assume caller calls free().
/
int sortArrayByParity(int* A, int ASize, int* returnSize){
if(!ASize){
*returnSize=0;
return NULL;
}int* ans=(int*)malloc(sizeof(int)*ASize);
int front=0,rear=ASize-1;
//直接插入
for(int i=0;i<ASize;++i){
if(A[i]&1)
ans[rear–]=A[i];
else
ans[front++]=A[i];
}
*returnSize=ASize;return ans;
}
//首尾双指针调换
/**
-
Note: The returned array must be malloced, assume caller calls free().
/
int sortArrayByParity(int* A, int ASize, int* returnSize){
if(!ASize){*returnSize=0;return NULL;}int* ans=(int*)malloc(sizeof(int)*ASize);
memcpy(ans,A,sizeof(int)*ASize);
int front=0,rear=ASize-1;
for(;front<rear;++front){
if(ans[front]&1){
int temp=0;
while((ans[rear]&1)&&front<rear) rear–;
temp=ans[front];
ans[front]=ans[rear];
ans[rear]=temp;
rear–;
}
}
*returnSize=ASize;return ans;
}
总结和反思:题目要求新建数组,所以使用直接插入明显更加简便,只不过需要花费额外的空间;
注意:使用双指针时要注意相遇时如何处理,通常情况下,相遇时即结束遍历。