前言
不用额外的空间是最基本的,这里介绍两种方法,快慢指针和双指针。
一、双指针
其思想类似于快排的划分,把左边发现的偶数放在靠右边,这样这两个数就不用在动它了。
1、源码
public int[] exchange(int[] nums) {
//双指针解法,从前开始寻找奇数,从后开始寻找偶数,寻找到就交换。直到相遇。
int i = 0, j = nums.length - 1;
int temp = 0;
while (i < j) {
while (nums[i] % 2 == 0 && i < j)
i++;
while (nums[j] % 2 == 1 && i < j)
j--;
temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
return nums;
}
二、快慢指针
一次遍历,找到奇数,就甩到前面去,前面没得到一个奇数,slow指针++。
1、源码
public int[] exchange2(int[] nums) {
//快慢指针,这样虽然会做一些无用的交换,但是思想可以理解一下
int slow = 0, temp = 0;
for (int i = 0; i < nums.length; i++) {
if ((nums[i] & 1) == 1) {
temp = nums[slow++];
nums[slow - 1] = nums[i];
nums[i] = temp;
}
}
return nums;
}
总结
方法一采用快排的思想,使用双指针,虽然while比较多,但是i++,j–让其遍历的时间复杂度为O(N),每一个数字都访问过。
方法二代码简洁,但是会出现无用的交换,比如奇数换奇数。也是一遍过,O(N),但是做的交换比方法一多。
可以感受其思路就行。快慢指针快速解题.