算法
(双指针扫描) $O(n)$
用两个指针分别从首尾开始,往中间扫描。扫描时保证第一个指针前面的数都是奇数,第二个指针后面的数都是偶数。
每次迭代时需要进行的操作:
- 第一个指针一直往后走,直到遇到第一个偶数为止;
- 第二个指针一直往前走,直到遇到第一个奇数为止;
- 交换两个指针指向的位置上的数,再进入下一层迭代,直到两个指针相遇为止;
时间复杂度
当两个指针相遇时,走过的总路程长度是 $n$,所以时间复杂度是 $O(n)$。
C++ 代码
class Solution {
public:
void reOrderArray(vector<int> &array) {
int l = 0, r = array.size() - 1;
while (l < r) {
while (l < r && array[l] % 2 == 1) l ++ ;
while (l < r && array[r] % 2 == 0) r -- ;
if (l < r) swap(array[l], array[r]);
}
}
};
给一段用sort的代码,奇数偶数相对位置不变
而且我如果写成
return (a&1)==(b&1)?1:(a&1);
,直接se了* 我认为当ab奇偶性一样的时候,ab谁先谁后都无所谓,返回01都行,为啥会报错呢
别开static,static声明是静态的
我把cmp写在class外面,去掉static,该超时还是超时,该se还是se
你把你的代码发一下,我这里没问题。。。
$emmm…$
建议你了解一下$sort$的具体方法再想想看,说不定就知道为啥了
对比了一下你俩的代码:
你的报se::return (a&1)==(b&1)?1:(a&1);
正确的: return (a&1)==(b&1)?0:(a&1);
如果二者皆为奇数或皆为偶数则:
应当return 0
而你的return 1
return 0时sort函数不会排序
return 1时会进行没必要的排序(将奇偶性相同的也排了一次),数据量大的时候会超时,数据小时能通过
好像快排啊
是啊,是啊,太像了,只不过把交换条件给变了
这两种差别在哪里呢?代码一可以通过,代码二不能通过
明白了,代码二的第三个if中会有left >= right的可能,加一个left < right 即可通过
问一下 如果这个函数在主函数中调用应该怎么样调用
???
谢大哥!祝大哥一路长红
也可以采用类似unique库函数的实现方式,保证奇数与奇数,偶数与偶数的相对位置关系不发生改变,缺点是需要额外的空间开销
快排的一种变种,代码量少点,但是理解起来不如Y总的
上述代码中,k指针在移动过程中检测奇数,并将奇数放到mi指针的前方,保证mi前面都为奇数,mi和mi后面的数都为偶数,缺点是在移动过程中,偶数之间的相对顺序变化了(奇数没有)
很棒。
快排划分区间的前后指针法,好思路
aaaaaaaaaaaaaaaaa,没想到快排
bool cmp(const int& a, const int& b){
return (a&1) > (b&1);
}
class Solution {
public:
void reOrderArray(vector[HTML_REMOVED] &array) {
sort(array.begin(), array.end(), cmp);
}
};
冒泡:
void reOrderArray(int *array, int length) {
if(length!=0)
{
int low=0;
int high=length-1;
while(low!=high)
{
for(int i=high;i>low;i–)
{
if(array[i]%2)
{
int temp=array[i-1];
array[i-1]=array[i];
array[i]=temp;
}
}
low++;
}
}
}
少了个排序吧,偶数部分和参考样例不同
不用sort 奇数偶数相对位置不变
太牛逼了
但是这个是不是还有排序过,题目的答案
真的很像二分和快排
二分快排!
为啥这种写法会 sf 呀?
我照着Y总的做法写了一遍,为啥输出的是[1, 5, 3, 4, 2] 而不是[1,3,5,2,4]呢?
可能是题目说把偶数全放后面,奇数全放前面,没有说按顺序放吧
那我就放心了
while (l < r && array[l] % 2 == 1) l ++ ;这个while循环岂不是一直跳不出来
碰上偶数不就跳出来了吗
最差的情况数组中全是奇数,i会一直加到j然后退出
好像快速排序的思路啊
这个和快排比起来,中间多了一个i < j,这是为啥?
差不多把,快排模板里面是do while,意思都是一样的,防止lr指针出边界
就是快速排序的轴点划分 只不过判断条件改了
’‘’
class Solution {
public:
void reOrderArray(vector[HTML_REMOVED] &array) {
int n = array.size();
vector[HTML_REMOVED] b;
for(int i = 0;i<n;i)
{
if(array[i]%2!=0)
b.push_back(array[i]);
}
for(int i = 0;i<n;i)
{
if(array[i]%2==0)
b.push_back(array[i]);
}
array = b;
}
};
‘’‘
直接愚蠢的开辟另一个数组先存奇数,再存偶数
也行啊
我的解法:
class Solution {
public:
void reOrderArray(vector[HTML_REMOVED] &array) {
vector[HTML_REMOVED]res;
int l=-1,r=array.size();
while(l<r){
do l++;while(l<r&&array[l]%2==1);
do r–;while(l<r&&array[r]%2==0);
if(l<r)swap(array[l],array[r]);
}
};
但是不知道为什么判断奇数偶数里面的while少了l<r会报错,有大佬讲解下吗?