我想把这期作为数组类面试题的一个总结,题目不难,但是要注意不要犯错,下面是容易犯错的地方:

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}