👀先看这里👈
😀作者:江不平
📖博客:江不平的博客
📕学如逆水行舟,不进则退
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
❀本人水平有限,如果发现有错误的地方希望可以告诉我,共同进步👍
🔍题目详情
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。并且保证奇数和奇数,偶数和偶数的相对位置不变。
示例
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
题目来源:[力扣(LeetCode)]
🤔解题思路
逻辑&步骤
删除线的内容作为拓展,先不看删除线的内容,不考虑相对顺序题目就变得简单起来,可以采用前后双指针的方法。两头开始遍历,头指针遇到奇数,尾指针遇到偶数,二者进行交换。
时间复杂度 :O(N)
空间复杂度 :O(1)
再看拓展后的题目,这里我们从头开始遍历数组,遇到奇数就保存下来,偶数往后移,再把奇数往前放,详见代码
时间复杂度 :O(N)
空间复杂度 :O(1)
💻代码实现
c++:
class Solution {
public:
vector<int> exchange(vector<int>& nums)
{
int i = 0, j = nums.size() - 1;
while (i < j)
{
while(i < j && (nums[i] & 1) == 1) i++;
while(i < j && (nums[j] & 1) == 0) j--;
swap(nums[i], nums[j]);
}
return nums;
}
};
扩展题目解法:
c++:
奇数前插的过程,还有偶数后插,这里就不写了
class Solution {
public:
vector<int> exchange(vector<int>& nums) {
int k = 0;
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] & 1) { //从左向右,每次遇到的,都是最前面的奇数,一定将来要被放在k下标处
int temp = nums[i]; //现将当前奇数保存起来
int j = i;//j代表的是当前奇数的位置
while (j > k) { //将该奇数之前的内容(偶数序列),整体后移一个位置,这里不能是=,移动的次数是一定的。
nums[j] = nums[j - 1];
j--;
} nums[k++] = temp; //将奇数保存在它将来改在的位置,因为我们是从左往右放的,没有跨越奇数,所以一定是相对位置不变的
}
}
return nums;
}
};
💬总结
- 决定一个数是奇偶,就二进制而言,就看第一个位置,因为其他位置都可以看成2的n次方。
- 注意循环的次数,这里的k,在写while循环时,逻辑上说第一次k确实为0,指的是数组的第一个位置,但是我们要考虑循环的次数,如果加了=,就会多循环一次,开区间是很容易看出来循环次数的,可读性强,一般用开区间。
- 这个题目较为简单,笔试中不常见,不过往往简单的这种题目拓展性很强,可以不断往外拓展,所以面试容易遇到。