在微博上看到一道题,虽然不难但也想了一段时间,所以就记录下来。
题目描述:
给定int数组,要求在O(n)的时间和O(1)的空间内将其中的奇数排在前面,偶数排在后面并保证相对位置不变。
例如 5 6 8 3 2 4 9 ----〉 5 3 9 6 8 2 4
虽然题目看似简单,但限制比较苛刻,也就是求一个线性时间内稳定的就地二值排序问题。
很遗憾我没法给出我思考的具体过程,这个题目的思路我更像是“灵机一动”想到的,而不是“有计划的一步一步推理”出来的。
假设A代表一个连续的奇数串,B代表一个连续的偶数串,则任何一个数组都可以表示成AB相邻出现的形式。
所以我们的目的就是把一串的ABABAB 变成 AB ,即奇数在前偶数在后。
所以算法就很简单了,假设数组为ABABABAB ,则按以下方法:
ABABABAB互换第一个BA,变成AABBABAB ,合并AA和BB两个串,变成ABABAB,重复这个过程直到串变成AB即可。
接着要寻找O(n)的AB互换的算法,例如A=1357 B=2468 经过变换后应该为2468 1357。
先将整串就地逆置(首尾互换,次首次尾互换以此类推),然后在将A和B分别逆置即可。
即 13572468--〉86427531--〉2468 1357 ,每个元素变了两次位置,所以是线性时间。