剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
示例:
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。
提示:
1 <= nums.length <= 50000
1 <= nums[i] <= 10000
解法1:
暴力方法一遍历数组,遇到偶数移到数组最后一个,其他的依次向前移动,时间复杂度高
public static int[] exchange(int[] nums) {
if(nums.length==0)return nums;
int i=0,con=0;
int end=nums[nums.length-1];
while(con<nums.length)
{
if(nums[i]%2==0)
{
int temp=nums[i];
for(int j=i;j<nums.length-1;j++) {
nums[j]=nums[j+1];
}
nums[nums.length-1]=temp;
i--;
}
i++;
con++;
}
return nums;
}
暴力方法二:新建两个数组,一个放奇数,一个放偶数
public static int[] exchange(int[] nums) {
ArrayList l1=new ArrayList();
ArrayList l2=new ArrayList();
for(int i=0;i<nums.length;i++)
{
if(nums[i]%2!=0)l1.add(nums[i]);
else l2.add(nums[i]);
}
int in=0;
for(int i=0;i<l1.size();i++)
{
nums[in]=(int) l1.get(i);
in++;
}
for(int i=0;i<l2.size();i++)
{
nums[in]=(int) l2.get(i);
in++;
}
return nums;
}
解法二:双指针方法
首尾双指针left和right,left向右扫描遇到偶数停下来,right向左扫描遇到奇数停下来,交换left和right指向的值,继续扫描,知道left和right相遇。
public static int[] exchange(int[] nums) {
if(nums.length==0)return nums;
int left=0;
int right=nums.length-1;
while (left < right) {
if ((nums[left]%2)!=0) {
left ++;
continue;
}
if ((nums[right]%2)==0) {
right --;
continue;
}
int temp=nums[left];
nums[left]=nums[right];
nums[right]=temp;
}
return nums;
}
或者
public static int[] exchange(int[] nums) {
if(nums.length==0)return nums;
int left=0;
int right=nums.length-1;
while (left < right) {
if(left<right&&nums[left]%2!=0)
left++;
if(left<right&&nums[right]%2==0)
right--;
int temp=nums[left];
nums[left]=nums[right];
nums[right]=temp;
}
return nums;
}
快慢双指针,
public static int[] exchange(int[] nums) {
int slow=0,fast=0;
while(fast<nums.length)
{
if(nums[fast]%2!=0)
{
if(slow!=fast)
{
int temp=nums[fast];
nums[fast]=nums[slow];
nums[slow]=temp;
}
slow++;//fast是奇数的时候slow才会+
}
fast++;
}
return nums;
}