必须倒序遍历内层循环,因为正向删除会改变后续元素索引导致漏删;倒序可确保未检查的索引不受影响。

用双重循环删除重复坐标点,核心是逐个比较每对点的 x 和 y 值是否完全相等,再从后往前删(避免索引错乱)。但要注意:这不是最优解,仅适用于小数据量或教学理解;实际项目中推荐用 Set 或 filter + findIndex 等更高效方式。
为什么必须倒序遍历内层循环?
正向遍历时,一旦删除某个元素,后续元素索引会前移,导致下一轮比较跳过相邻项,漏删重复点。倒序遍历(如 j = arr.length - 1; j > i; j--)可确保每次删除都不影响尚未检查的索引。
- 错误示例(正向删):
for (let j = i + 1; j → 删掉 <code>arr[3]后,原arr[4]变成arr[3],但j已变成 4,直接跳过 - 正确做法:内层从末尾开始,
j递减,删完不影响前面未检查的下标
基础双重循环去重代码(保留第一个出现的点)
假设坐标点是形如 {x: 1, y: 2} 的对象数组:
function removeDuplicatePoints(points) {
for (let i = 0; i i; j--) {
if (points[i].x === points[j].x && points[i].y === points[j].y) {
points.splice(j, 1);
}
}
}
return points;
}
<p>// 示例
const pts = [{x: 1, y: 2}, {x: 3, y: 4}, {x: 1, y: 2}, {x: 5, y: 6}];
console.log(removeDuplicatePoints(pts));
// → [{x: 1, y: 2}, {x: 3, y: 4}, {x: 5, y: 6}]
</p>
如果坐标是数组形式 [x, y],怎么改?
只需把属性比较换成数组索引比较:
points[i][0] === points[j][0] && points[i][1] === points[j][1]- 或者用展开语法简写判断:
JSON.stringify(points[i]) === JSON.stringify(points[j])(仅限简单结构,不推荐用于含函数/undefined 的数据)
注意:JSON.stringify 方案虽简洁,但性能差、无法处理 NaN、undefined、循环引用,仅作临时调试用。
更推荐的现代写法(非双重循环)
虽然题目问双重循环,但实际开发中应优先考虑清晰且高效的替代方案:
- 用
Set+ 字符串键去重:[...new Set(points.map(p => `${p.x},${p.y}`))].map(s => { const [x,y] = s.split(','); return {x:+x, y:+y}; }) - 用
filter+findIndex:points.filter((p, i) => points.findIndex(q => q.x === p.x && q.y === p.y) === i) - 用
Map记录已见坐标:const seen = new Map(); return points.filter(p => { const key = `${p.x},${p.y}`; if (seen.has(key)) return false; seen.set(key, 1); return true; });
这些方法时间复杂度接近 O(n),远优于双重循环的 O(n²),尤其当点数超过几百时差异明显。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











