【LeetCode & 剑指offer刷题】数组题13:21 调整数组顺序使奇数位于偶数前面
【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)
21 调整数组顺序使奇数位于偶数前面
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,
所有的偶数位于数组的后半部分,并保
证奇数和奇数,偶数和偶数之间的相对位置不变。
/*
方法:用一个临时数组存奇数和偶数,联系问题odd even linked list
O(n), O(n)用空间换时间
*/
#include
class
Solution
{
public
:
void
reOrderArray
(
vector
<
int
>
&
a
)
{
if
(
a
.
empty
())
return
;
vector
<
int
>
result
;
for
(
int
i
=
0
;
i
<
a
.
size
();
i
++)
{
if
(
a
[
i
]
%
2
==
1
)
result
.
push_back
(
a
[
i
]);
}
for
(
int
i
=
0
;
i
<
a
.
size
();
i
++)
{
if
(
a
[
i
]
%
2
==
0
)
result
.
push_back
(
a
[
i
]);
}
a
=
result
;
}
};
/*
无法保证调整后,奇数与奇数之间,偶数与偶数之间相对位置不变(可优化,用stable_partition,O(nlogn))
和partition函数比较像
O(n), O(1)
*/
void
reOrderArray
(
vector
<
int
>
&
a
)
{
if
(
a
.
empty
())
return
;
int
left
=
0
,
right
=
a
.
size
()-
1
;
while
(
left
<
right
)
//
从两边向中间扫描
{
//
向右移动
left
指针,直到指向偶数
while
(
left
<
right
&&
a
[
left
]%
2
!=
0
)
left
++;
//
若为奇数时,向前移动
//
向左移动
right
,直到指向奇数
while
(
left
<
right
&&
a
[
right
]%
2
==
0
)
right
--;
//
交换
swap
(
a
[
left
],
a
[
right
]);
}
}
链接: https://www.nowcoder.com/questionTerminal/beb5aa231adc45b2a5dcc5b62c93f593?toCommentId=460671
来源:牛客网
/**
* 1.要想保证原有次序,则只能顺次移动或相邻交换。
* 2.i从左向右遍历,找到第一个偶数。
* 3.j从i+1开始向后找,直到找到第一个奇数。
* 4.将[i,...,j-1]的元素整体后移一位,最后将找到的奇数放入i位置,然后i++。
* 5.終止條件:j向後遍歷查找失敗。
*/
联系partition函数
//
分割函数
//
选择一枢轴分割序列,并返回其位置
int
partition
(
vector
<
int
>&
a
,
int
left
,
int
right
)
{
//1.
初始化,用序列的第一个元素作为枢轴(也可用其他元素,但是要把枢轴元素暂时放到起始位置,方便后续交换,如三数中值初始化枢轴)
//2. median3
//3. srand((unsigned)time(NULL));
用随机法较简单
// int pivotPos = rand() % (right - left) + left; //
得到随机基元的位置
(
下标
)
// swap(a[pivotPos], a[left]) //
将枢轴暂时放入起始位置
int
pivot
=
left
;
while
(
left
<
right
)
//
从序列的两端交替地向中间扫描(在此循环中a[pivot]不动,退出循环后在被交换)
{
//
先right再left(因为left初始等于pivot),
以使
left
最后指向等于枢轴位置元素或者小于枢轴位置的元素(这样最后a[pivot]与
a[left]
交换才不会出错?)
while
(
left
<
right
&&
a
[
right
]
>=
a
[
pivot
])
right
--;
//
找到本次扫描中第一个不满足枢轴规律的高位数
while
(
left
<
right
&&
a
[
left
]
<=
a
[
pivot
])
left
++;
//
找到本次扫描中第一个不满足枢轴规律的低位数
swap
(
a
[
left
],
a
[
right
]);
//
交换以使满足枢轴规律
}
//
最后结果是
left
和
right
均指向枢轴位置
swap
(
a
[
left
],
a
[
pivot
]);
//
将枢轴移动到位
return
left
;
//
返回枢轴位置
}
推广:
-
可以把while中的第二个条件剥离出来,变成一个函数指针,以传入不同规则(判断数字应该在前半部分还是在后半部分)
-
STL中partition函数的做法
-
如果要保证调整后,各自部分的相对顺序不变,则可用stable_partition函数
-
-
问题举例
-
调整数组使奇数在前,偶数在后
-
调整数组使小于某个数(pivot)的数在前,大于的在后
-
调整数组使负数在前,非负数在后
-
调整数组使能被3整数的数在前,不能整数的在后
-
posted @
2019-01-05 14:19 wikiwen 阅读(
...) 评论(
...) 编辑 收藏