题目描述
给定⼀个⾮负整数数组 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 <= 5000 0 <= A<= 5000
方法一
想法和算法
⾸先定义两个空列表 odd 和 even ,然后遍历整个列表,将列表中的奇数元素放⼊ odd 列表中,偶 数元素放⼊ even 列表中,然后将两个列表相加并返回。
实现
[Python]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 | class Solution: def sortArrayByParity(self, A: List[int]) -> List[int]: odd = [] even = [] for a in A: if a % 2 == 0: even.append(a) else: odd.append(a) return even + odd |
复杂度分析
时间复杂度: O(N) ,其中 N 是列表 A 的⻓度;
空间复杂度: O(N)
方法二
想法如果希望原地排序,可以使⽤快排,⼀个经典的算法。
算法
维护两个指针 i 和 j ,保证循环不变量:
1. 对于任意索引⼩于 i 的元素都是偶数;
2. 对于任意索引⼤于 j 的元素都是奇数。
从⽽,( A % 2 , A[j] % 2 )的值有4中情况需要处理:
1. 如果为(0, 1),那么 i++, j--;
2. 如果为(1, 0),那么交换 i 和 j;
3. 如果为(0, 0),那么说明 i 的位置是正确的,只能 i++;
4. 如果为(1, 1),那么说明 j 的位置是正确的,只能 j--;
通过这4种情况,可以保证 j-i 的值可以不断缩⼩,最终就可以得到奇偶有序的数组。
1. 对于任意索引⼩于 i 的元素都是偶数;
2. 对于任意索引⼤于 j 的元素都是奇数。
从⽽,( A % 2 , A[j] % 2 )的值有4中情况需要处理:
1. 如果为(0, 1),那么 i++, j--;
2. 如果为(1, 0),那么交换 i 和 j;
3. 如果为(0, 0),那么说明 i 的位置是正确的,只能 i++;
4. 如果为(1, 1),那么说明 j 的位置是正确的,只能 j--;
通过这4种情况,可以保证 j-i 的值可以不断缩⼩,最终就可以得到奇偶有序的数组。
实现
[Python]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 11 12 13 | class Solution: def sortArrayByParity(self, A: List[int]) -> List[int]: i = 0 j = len(A) - 1 while i < j: # 必须先进⾏交换,再做判断进⾏ i 和 j 的运算,否则会导致多循环⼀次,中间的两个数错误 if A % 2 == 1 and A[j] % 2 == 0: A, A[j] = A[j], A if A % 2 == 0: i = i + 1 if A[j] % 2 == 1: j = j - 1 return A |
复杂度分析
时间复杂度: O(N) ,其中 N 是列表 A 的⻓度,循环的每⼀步都让 j-i ⾄少减少了 1;
空间复杂度: O(1) ,不需要额外空间。
更多技术资讯可关注:itheimaGZ获取