头尾指针法
大体思想如下
- 建立头指针 l e f t left left和尾指针 r i g h t right right,分别指向当前最左侧奇数元素的索引和最右侧的偶数元素的索引。
- 初始化 l e f t left left和 r i g h t right right,分别为首索引和尾索引
- l e f t left left不断右移,直到指向偶数元素
- r i g h t right right不断左移,直到指向奇数元素
- 交换 n u m s [ l e f t ] nums[left] nums[left]和 n u m s [ r i g h t ] nums[right] nums[right]
// 可以考虑用头尾指针法
// 头指针指向奇数,尾指针指向偶数
// 头指针对数组进行遍历,遇到奇数就遍历下一个
// 遇到偶数就与尾指针交换,尾指针左移,重复此过程,直到头指针
// 指向奇数
// 测试用例,长度为1的数组,全为奇数或者偶数的数组
class Solution {
public int[] exchange(int[] nums) {
int left = 0;
int right = nums.length - 1;
while(left < right){
while(left < right && (nums[left] & 0x1) == 0){
// swap(nums[left], nums[right]);
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
right--;
}
left++;
}
return nums;
}
}
// 测试用例,长度为1的数组,全为奇数或者偶数的数组
class Solution {
public int[] exchange(int[] nums) {
int left = 0;
int right = nums.length - 1;
while(left < right){
// left右移,直到遇到偶数元素
if((nums[left] & 0x1) == 1){
left++;
continue;
}
// right,直到遇到奇数元素
if((nums[right] & 0x1) == 0){
right--;
continue;
}
// 交换
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
// 首尾指针都移动
left++;
right--;
}
return nums;
}
}
算法复杂度
- 时间复杂度: O ( n ) O(n) O(n),遍历和交换最多要 n n n
- 空间复杂度: O ( 1 ) O(1) O(1),所引入的变量占的空间为常数。
快慢指针法
- 建立两个指针 f a s t fast fast和 s l o w slow slow,分别指向下一个奇数元素和下一个奇数元素应当存放的位置
- 将 f a s t fast fast和 s l o w slow slow均初始化为 0 0 0
- f a s t fast fast右移,直到遇到奇数元素。将其与 s l o w slow slow指向的元素交换
// 测试用例,长度为1的数组,全为奇数或者偶数的数组
class Solution {
public int[] exchange(int[] nums) {
// slow指向
int fast = 0;
int slow = 0;
while(fast < nums.length){
if((nums[fast] & 0x1) == 1){
int temp = nums[slow];
nums[slow] = nums[fast];
nums[fast] = temp;
slow++;
}
fast++;
}
return nums;
}
}
算法复杂度
- 时间复杂度: O ( n ) O(n) O(n),遍历和交换最多要 n n n
- 空间复杂度: O ( 1 ) O(1) O(1),所引入的变量占的空间为常数。