本文详解使用栈结构消除相反方向(如NORTH/SOUTH、EAST/WEST)的算法原理,重点解析stack[stack.length - 1]的安全访问逻辑、空栈边界行为,以及为何不会因读取未定义值导致错误。
本文详解使用栈结构消除相反方向(如north/south、east/west)的算法原理,重点解析`stack[stack.length - 1]`的安全访问逻辑、空栈边界行为,以及为何不会因读取未定义值导致错误。
该函数 dirReduc 的核心思想是:利用栈的“后进先出”特性,实时匹配并抵消相邻的相反方向。例如,['NORTH', 'SOUTH'] 应被完全移除;而 ['NORTH', 'EAST', 'SOUTH'] 中,NORTH 与 SOUTH 不相邻,故不抵消——但本算法通过栈动态维护“尚未被抵消的方向序列”,使非相邻但可间接抵消的方向也能被处理(如 ['NORTH', 'SOUTH', 'SOUTH'] → 先抵消前两个,留下 ['SOUTH'])。
关键点在于对 stack[stack.length - 1] 的访问:
下面是一个带调试注释的增强版实现:
function dirReduc(arr) { const stack = []; for (let direction of arr) { const last = stack[stack.length - 1]; // 可能为 undefined(空栈时) // 只有当栈非空且方向相反时才抵消 const isOpposite = (direction === 'NORTH' && last === 'SOUTH') || (direction === 'SOUTH' && last === 'NORTH') || (direction === 'EAST' && last === 'WEST') || (direction === 'WEST' && last === 'EAST'); if (isOpposite) { stack.pop(); // 抵消:移除栈顶 console.log(`抵消: ${last} ←→ ${direction}, 栈变为 [${stack.join(', ')}]`); } else { stack.push(direction); // 累积:入栈 console.log(`入栈: ${direction}, 栈变为 [${stack.join(', ')}]`); } } return stack;}// 示例调用console.log(dirReduc(['NORTH', 'SOUTH', 'EAST', 'WEST'])); // → []console.log(dirReduc(['NORTH', 'SOUTH', 'SOUTH', 'EAST', 'WEST', 'WEST'])); // → ['SOUTH', 'WEST']
⚠️ 注意事项:
总结:栈在此处扮演“待决方向缓冲区”的角色;stack[stack.length - 1] 的巧妙之处,在于它天然兼容空栈场景,无需额外 if (stack.length > 0) 判断——这正是函数简洁而健壮的关键设计。