leetcode-922 Sort Array By Parity II

922. Sort Array By Parity II

Description

Given an array A of non-negative integers, half of the integers in A are odd, and half of the integers are even.

Sort the array so that whenever A[i] is odd, i is odd; and whenever A[i] is even, i is even.

You may return any answer array that satisfies this condition.

Example 1:

1
2
3
Input: [4,2,5,7]
Output: [4,5,2,7]
Explanation: [4,7,2,5], [2,5,4,7], [2,7,4,5] would also have been accepted.

Note:

  1. 2 <= A.length <= 20000
  2. A.length % 2 == 0
  3. 0 <= A[i] <= 1000

Analyse

A是一个非负整数数组,一半奇数一半偶数

A进行排序,使A的奇数位置为奇数,偶数位置为偶数

使用两个int变量存储奇数和偶数的位置

even(偶) 存储第一个存了奇数的偶数位置

odd(奇) 存储第一个存了偶数的奇数位置

每一趟循环都找一遍oddeven,然后交换这两个位置的值,进入下一次循环

下面是第一个版本的代码,写完后AC,甚至能faster than 100.00%

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
vector<int> sortArrayByParityII(vector<int>& A) {
int even = 0; // first even position with a odd
int odd = 1; // first odd position with a even

for(int i = 0; i < A.size(); i++)
{
while ((A[even] % 2 == 0) && (even < A.size() - 1))
{
even += 2;
}

while ((A[odd] % 2 != 0) && (odd < A.size()))
{
odd += 2;
}

if ((i % 2) != (A[i] % 2))
{
int tmp = A[even];
A[even] = A[odd];
A[odd] = tmp;
}

}
return A;
}

但是这个版本代码的循环退出条件有点怪,比如这些地方,for循环出现就很诡异,这个if判断后交换两元素的值也是,算出evenodd后并不一定会立即交换,而是会等到遍历到奇数位不为奇数或偶数位不为偶数时才交换,最后虽然能交换成功,但总归是不太好的解法

我也不知道这个版本我怎么写出来的,似乎是在for循环输出vector的代码基础上改的

1
2
3
4
5
6
7
8
for(int i = 0; i < A.size(); i++)

if ((i % 2) != (A[i] % 2))
{
int tmp = A[even];
A[even] = A[odd];
A[odd] = tmp;
}

继续写第二个版本,思考循环终止条件,循环终止的时候每个奇数位都是奇数,偶数位都是偶数了

再计算evenodd的时候就会大于A.size(),使用这个当作循环结束的条件(copy了LeetCode上的代码)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
vector<int> sortArrayByParityII(vector<int>& A) {
int even = 0; // first even position with a odd
int odd = 1; // first odd position with a even

while ((even < A.size() - 1) && odd < A.size())
{
while ((A[even] % 2 == 0) && (even < A.size() - 1))
{
even += 2;
}

if (even >= A.size() - 1)
{
break;
}

while ((A[odd] % 2 != 0) && (odd < A.size()))
{
odd += 2;
}

if (odd >= A.size())
{
break;
}

int tmp = A[even];
A[even] = A[odd];
A[odd] = tmp;
}
return A;
}