题目描述:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
示例:
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。
提示:
1 <= nums.length <= 50000
1 <= nums[i] <= 10000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
这题如果新建一个数组,遍历两次数组把数组的元素依次放进新数组里面,没什么难度,但是多用了一些内存空间。还可以设置内外两个循环,一次遍历完成,但是实现复杂,而且时间复杂度上去了。
这道题想到的是用双指针的方法:头指针指向数组的第一个元素,尾指针指向数组的最后一个元素,头指针从前往后,尾指针从后往前,当头指针小于尾指针的时候执行循环。
头指针和尾指针指向的数无非有4种情况:
1、头指针指向的数是偶数,尾指针指向的数是奇数。这种情况就交换两个数的位置,处理完之后,头尾指针分别指向下一个数。
2、头指针是奇数,尾指针也是奇数。这种情况头指针的内容在前半部分,符合题目要求,尾指针的数是奇数,应该是要被放到前半部分的,所以这时尾指针不动,头指针指向下一个数,直到找到一个偶数,和尾指针指向的数交换位置。
3、头指针是偶数,尾指针也是偶数。这种情况尾指针的内容在后半部分,符合题目要求,头指针的数是偶数,应该是要被放到后半部分的,所以这时头指针不动,尾指针指向下一个数,直到找到一个偶数,和头指针指向的数交换位置。
4、头指针指向的数是奇数,尾指针指向的数是偶数。这种情况,前后两个数都符合题目要求,不用交换为位置,直接指向下一个数。
代码(Java):
public class doingmyself {
public static void main(String[] args) {
int[] nums = {1,2,3,4,5,6,7,8,9,10};
int[] ans = exchange(nums);
for(int num:ans) {
System.out.print(num + "\t");
}
}
public static int[] exchange(int[] nums) {
int p1 = 0; //前指针
int p2 = nums.length-1; //后指针
while(p1 < p2) { //当前指针比后指针小的时候就执行循环
if(iseven(nums[p1]) && isodd(nums[p2])) { //找到前指针的数是偶数,后指针的数是偶数,交换位置,并前后指针都指向下一个数
int temp = nums[p1];
nums[p1] = nums[p2];
nums[p2] = temp;
p1++;
p2--;
}else if(isodd(nums[p1]) && isodd(nums[p2])) { //前指针是奇数,后指针也是奇数,后指针是需要一到前面的,前指针是不用动的
p1++; //前指针指向下一个数,等待找到一个偶数和后指针的数交换
}else if(iseven(nums[p1]) && iseven(nums[p2])) {//前指针是偶数,后指针也是偶数,前指针的数是需要移动到后面的,后指针的
p2--; //数是不用动的,后指针指向下一个数,等待找到一个技术和前指针的数交换
}else if(isodd(nums[p1]) && iseven(nums[p2])) { //前指针是奇数,后指针的数是偶数,符合要求,两个指针都指向下一个数
p1++;
p2--;
}
}
return nums;
}
//定义判断数组元素是不是奇数的函数
public static boolean isodd(int num) {
if(num % 2 == 1) return true;
return false;
}
//定义判断数组元素是不是偶数的函数
public static boolean iseven(int num) {
if(num % 2 == 0) return true;
return false;
}
}