/** * @param {number[]} nums * @return {number[][]} */var threeSum = function (nums) { nums.sort((a, b) => a - b); let len = nums.length; let ans = []; for (let i = 0; i < len; ++i) { if (i > 0 && nums[i] === nums[i - 1]) continue; // 不重复枚举 let tar = -nums[i]; let r = len - 1; for (let l = i + 1; l < len; ++l) { if (l > i + 1 && nums[l] === nums[l - 1]) continue; // 不重复枚举 while (l < r && nums[l] + nums[r] > tar) --r; if (l === r) break; if (nums[l] + nums[r] === tar) { ans.push([nums[i], nums[l], nums[r]]); } } } return ans;};
单调栈,维护一个单调递减的栈(存的是下标),遍历高度数组 h[r],每次与栈顶比较,若栈不为空且 h[r] 大于栈顶,则将栈顶出栈为 top ,若此时栈为空则说明前面没有能挡住水的地方故不需计算结束,将 h[r] 入栈;若不为空则将此时的栈顶元素即 l 与当前元素 r 比较高度,取较矮的那个(min(height[l], height[r]))减去 h[top] 作为高度,宽度则为 r-l-1,
完整代码
/** * @param {number[]} height * @return {number} */var trap = function (height) { let s = []; // 存下标 let ans = 0; let l = 0; let n = height.length; for (let r = 0; r < n; ++r) { let size = s.length; while (size != 0 && height[r] > height[s[size - 1]]) { // 跟栈顶比较 let top = s.pop(); // 栈顶出 --size; if (size == 0) break; l = s[size - 1]; // 为栈顶底下的一个元素 ans += (r - l - 1) * (Math.min(height[l], height[r]) - height[top]); // 宽*高 } s.push(r); // 小于等于栈顶,则进栈 } return ans;};
先使用 Remark42 作为临时评论系统,样式等有待优化