前言
最近发现一个公众号,每天一道题,难度也不大,而且题干很短,搜了下,题都是LintCode这个平台的,今天注册了小号做了做,中文很友好(和LeetCode相比,可以说造福广大吃瓜群众),然后可以看到哪个用例过不去(造福非ACMer,看到WA就“卧槽,咋可能错了”的选手),并且类似LeetCode,只用写关键的方法,不用去管格式化输出输入。
正文
LintCode 144 交错正负数
描述:
给出一个含有正整数和负整数的数组,重新排列成一个正负数交错的数组。
样例:
给出数组[-1, -2, -3, 4, 5, 6],重新排序之后,变成[-1, 5, -2, 4, -3, 6]或者其他任何满足要求的答案.
我的思路很简单,因为没有要求必须是正开头或者必须是负开头,只要A[1]A[3]A[5]….与A[0]符号不同,A[2],A[4],A[6]…与A[0]符号相同就满足要求。
于是就写下这样的代码:
class Solution {
public:
/*
* @param A: An integer array.
* @return: nothing
*/
void rerange(vector<int> &A) {
int flag = A[0];
vector<int>::iterator i = A.begin() + 1; //A[1] A[3] A[5]等
vector<int>::iterator j = A.begin() + 2; //A[2] A[4] A[6]等
while(i < A.end() && j < A.end()){
while(*i * flag < 0 ) //在奇数位置与A[0]异号,不满足则跳出循环
i = i + 2;
while(*j * flag > 0 )//在偶数位置与A[0]同号,不满足则跳出循环
j = j + 2;
if(i < A.end() && j < A.end()){//交换
int temp = *i;
*i = *j;
*j = temp;
}else
break;
i = i + 2;
j = j + 2;
}
}
};
卡在65%。。。
然后就华丽地卡在65%这个例子过不去。。。
那个例子我的输出最后几个出现了同号,于是看了看别人的题解,发现别人上来就在比较正负数的数量,或者排序啥的。。。
What ???(吕白问号.jpg)
正确的思路
emmmmm,改不出来,就先去吃饭了,在路上想了想,给Axin讲了讲,一下子就get到之前思路的错误了。
因为是交错的,所以正负数之间的数量关系有三种:
1.正负数一样多,比如2正2负,这时顺序可以是 正负正负,或者负正负正。
2.正数比负数多一个,比如3正2负,这时顺序必须是 正负正负正。
3.负数比正数多一个,同上,必须是负正负正负。
而我之前的顺序是将A[0]作为基准的,也就是说,当输入样例为
1,2,-1,-2,-3
时,我的输出结果是1,-1,2,-2,-3
,很明显最后出现了同号。。。
于是只好老实的在原来代码上改一下了。
int a = 0, b = 0,length = A.size();
for(auto i : A){ //遍历,a记录正数,b记录负数
if(i > 0)
a++;
else
b++;
}
if(a > b && A[0] < 0){//正数多,并且A[0]为负数
for(int i = 1; i < length; i++)//找到一个正数,和A[0]交换
if(A[i] > 0){
swap(A[0],A[i]);
break;
}
}
if(b > a && A[0] > 0){//负数多,并且A[0]为正数
for(int i = 1; i < length; i++)//找到一个负数,和A[0]交换
if(A[i] < 0){
swap(A[0],A[i]);
break;
}
}
//下面就是最开始的代码了
Ok,这下我们就保证了A[0]的符号一定是正确的了,然后顺利AC。。。