🚀 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。
🚁 个人主页:不 良
🔥 系列专栏:🛸剑指 Offer 🛹Linux
📕 学习格言:博观而约取,厚积而薄发
🌹 欢迎进来的小伙伴,如果小伙伴们在学习的过程中,发现有需要纠正的地方,烦请指正,希望能够与诸君一同成长! 🌹
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
题目:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。
示例:
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。
提示:
0 <= nums.length <= 50000
0 <= nums[i] <= 10000
思路一:
双指针。
设定两个指针
left
和right
分别指向数组的左边和右边,然后通过计算判断数组中这两边是奇数还是偶数并且分情况进行操作
当
nums[left] % 2 = 0
即左边为偶数且nums[right] % 2 = 1
即右边为奇数时,交换然后移动左右指针;当
nums[left] % 2 = 1
即左边为奇数时,left++
即可,因为此时如果当nums[right] % 2 = 1
,那么right
指针是不能移动的,所以只要当nums[left] % 2 = 1
,就只移动left
;当
nums[right] % 2 = 0
即右边为偶数时,right--
即可,因为此时如果当nums[left] % 2 = 0
,那么left
指针是不能移动的,所以只要当nums[right] % 2 = 0
,就只移动right
;剩下的情况就是左边和右边同时满足条件
nums[right] % 2 = 0
和nums[left] % 2 = 1
,直接left++,right--
。
代码如下:
class Solution {
public:
vector<int> exchange(vector<int>& nums) {
int left = 0;
int right = nums.size() - 1;
//比较
while(left < right) //循环条件left < right
{
//当左边%2为0即左边为偶数且右边%2为1即右边为奇数时,交换然后移动指针
if(nums[left] % 2 == 0 && nums[right] % 2 == 1)
{
swap(nums[left],nums[right]);
right--;
left++;
}
//当左边为奇数时,左边++即可
else if(nums[left] % 2 == 1)
{
left++;
}
//当右边为偶数时,右边--即可
else if(nums[right] % 2 == 0)
{
right--;
}
//剩下的情况就是左边和右边都满足条件,直接left++,right--
else{
right--;
left++;
}
}
//最后返回nums
return nums;
}
};
时间复杂度:
O(N)
空间复杂度:
O(1)
思路二:
开新的数组+双指针。
1.开一个数组
v
空间大小和nums
大小相同,定义两个指针left
和right
,分别从新数组的两边插入数值;2.遍历
nums
数组,判断数组中当前值是偶数还是奇数
如果是奇数就放到新数组
v
的左边;如果是偶数就放到新数组
v
的右边;
代码如下:
class Solution {
public:
vector<int> exchange(vector<int>& nums) {
int n = nums.size();
vector<int> v(n); //实例化n个int类型
int left = 0;
int right = nums.size() - 1;
for(auto e : nums)
{
//当为奇数时,左边插入
if(e % 2 == 1)
{
v[left++] = e;
}
//当为偶数时,右边插入
else
{
v[right--] = e;
}
}
return v;
}
};
时间复杂度:
O(N)
空间复杂度:
O(N)