看到这道题,我基本就觉得很熟悉,貌似在C++ Primer 5th里面出现过。只不过习题里出现的,是在std::vector<std::string>
删除重复的words,涉及到STL的话,就要减少不少难度。
这道题给的就是数组,联系之前的一道题,我们知道,在数组中删除某个元素的含义是:将这个元素放到size之外。譬如题目里给的例子:
[1,1,2]
我们就考虑将其变为:[1,2,1]或[1,2,2],然后返回size为2即可。也就是说,size范围之外的东西,完全没必要考虑,那就等于删除。
所以我考虑赋值法,即设置两个游标,一个指向数组的长度,一个遍历整个数组,然后遇到不重复项,则将数组长度指向的位置赋值为该不重复项,然后长度加一。
所以我写下了如下代码:
int size = 1;
if (n == 0 || n == 1) return n;
for (int j = 1, curv = A[0]; j != n; ++j)
{
if (curv != A[j])
{
A[size++] = A[j];
curv = A[j];
}
}
return size;
基本表述了我上述的思路,但是略显啰嗦。曾经说过的,EASY难度的题,顶多五行。好吧,咱们看看有没有什么优化的空间。
首先,开始的判断语句可以缩减为:if (n < 2) return n;
但这并不是本质的改变,我们再细细考虑下各个变量,size肯定不能省,j是遍历用的,肯定也不能省。剩下一个curv,代表的是不重复数组中最新的那个值。但别忘了这个数组是有序的,所以curv == A[i-1]
其实是永远成立的。考虑到这一步,才是真正的简化。
OK,算是一个满意的答案。