存在重复元素 III

对于getId()方法,由于这题的值域范围限制是[-10^9, 10^9],总数量没有超过有符号整型的正数范围,所以完全可以用更简单的平移法来生成id,避免更多的推导。

int getId (int x, int w){
return(x + 1000000000) / (w +1);
}

类似的平移法在很多记录状态的算法(DFS、记忆化搜索)中很常见,直观且方便。其实除法本来在0附近是连续的——例如,y = x / 10是一条穿过(0, 0)的直线;但进入到离散域(整型),由于程序舍入是按二进制执行的,小于0时是向上(大)舍入,大于0时是向下(小)舍入,这就导致0附近的值出现了偏差。题解采用的方式是手动修复这种偏差,而平移法想做的是直接避过这个偏差,让所有值都是正数。更有甚者,我们还可以直接在连续域上进行计算,这样也可以避过这个偏差:

int getId(int x, int w) {
return floor((x + 0.0) / (w + 1));
}