我想把这期作为数组类面试题的一个总结,题目不难,但是要注意不要犯错,下面是容易犯错的地方:
1. ++,--后索引有可能不满足我们假设的条件,一般情况都需要判断,使用while,for,if进行条件检查;
2. ++,-- 和break或者continue配合时,可别搞乱了顺序
题目1: Given an array with positive, negative and zeros, arrange the given array such that negatives are on left, zeros in the middle and positives on the right.
打眼一看,这个问题特别简单,不就是两头遍历,然后交换吗,确实是这样子,思想特别简单,但是实现起来就容易出错了,下面是我的版本:
#include <iostream> using namespace std; void groupInteger(int *data, int len) { int i = 0, j = len-1; while(i<j) { if(data[i]<0 ) i++; if(data[j]>=0) j--; if(data[i]>=0 && data[j]<0 && i<j) //不要落了i<j这个条件,因为前面有i++ 和 j++,而且一旦不满足i<j这个条件,我们不应该做swap swap(data[i++], data[j--]); } i = j; if(data[j]<0) //这里的i应该从什么地方开始呢?这需要我们对上一个while循环的结束条件非常了解,data[j]>=0 或者 swap后j的位置或者j本身>=0,或者j+1的位置>=0 i++; j = len -1; while(i<j) { if(data[i]==0 ) i++; if(data[j]>0) j--; if(data[i]>0 && data[j]==0 && i<j) //交换的条件是什么? 因为跟上面的代码非常类似,很容易Copy过来,但这也是容易导致错误的地方 swap(data[i++], data[j--]); } } int main(int argc, char **argv) { int src[] = {1,2,3,1,2,3}; groupInteger(src,sizeof(src)/sizeof(int)); for(int i= 0 ;i<sizeof(src)/sizeof(int);i++) cout<<src[i]<<","; cout<<endl; }
这个题目也是很有意思的,设计一下测试用例吧(这里只是验证功能,所以就只设计Functional cases):
1, {-1,0,2}
2, {2,0,-1,}
3, {-2,-2,3}
4, {-1,2}
5, {-1,0}
6, {1,2,3}
7, {0,0,0,0}
8, {-1,-2,-3,-4}