一、p129-JZ21使奇数位于偶数前面(不考虑相对位置)(hoare快排双指针)

如果不考虑相对位置的话,那么我们可以模仿hoare快排,使用双指针的思想,一个指针在前向后找偶数,一个指针在后,向前找奇数,然后再交换就行 时间复杂度是n
class Solution {
public:
vector<int> reOrderArrayTwo(vector<int>& nums) {
//用双指针
int n = nums.size();
if (n == 0) return{};
int left = 0, right = n - 1;
//左边找偶数,右边找奇数 然后交换
while (left < right) {
while (left < right && nums[left] & 1) ++left;
while (left < right && (nums[right] & 1) == 0) --right;
if (left < right) swap(nums[left], nums[right]);
}
return nums;
}
};
二、p129-JZ21使奇数位于偶数前面(考虑相对位置)(插入排序)

因为要考虑相对位置,所以我们就要借鉴一下插入排序的思想
class Solution {
public:
vector<int> reOrderArray(vector<int>& nums) {
//奇数位于偶数前面,并且还要保证相对位置不变
//那就得用到插入排序的思想了! //从前往后 看到奇数我就想办法往前挪
//1 3 5 6 7
int n = nums.size();
int k = 0;
for (int i = 0; i < n; ++i)
if (nums[i] &
1) { //从左向右,每次遇到的,都是最前面的奇数,一定将来要被放在k下标处
int temp = nums[i]; //先将当前奇数保存起来
int j = i;
while (j > k) { //将该奇数之前的内容(偶数序列),整体后移一个位置
nums[j] = nums[j - 1];
--j;
}
//将奇数保存在它将来改在的位置,因为我们是从左往右放的,没有跨越奇数,所以一定是相对位置不变的
nums[k++] =temp;
}
return nums;
}
};
扩展:如果面试官问你如果想要把题目改成将负数放在非负数前面,或者将可以被3整除的放在不能被3整除的数的前面,这个时候我们可以通过传入仿函数来设计一套通用的解法,然后只需要在判断的逻辑那里调用仿函数可以。这样可以实现解耦成两部分:一是判断数字应该在数组的前半部分还是后半部分的标准,而是拆分数组的操作。
三、p249-JZ51数组中的逆序对(归并排序)



最低0.47元/天 解锁文章
172万+





