diff --git "a/problems/0042.346円216円245円351円233円250円346円260円264円.md" "b/problems/0042.346円216円245円351円233円250円346円260円264円.md" index b232ce2206..060c0b4578 100644 --- "a/problems/0042.346円216円245円351円233円250円346円260円264円.md" +++ "b/problems/0042.346円216円245円351円233円250円346円260円264円.md" @@ -744,6 +744,91 @@ var trap = function(height) { }; ``` +### TypeScript + +双指针法: + +```typescript +function trap(height: number[]): number { + const length: number = height.length; + let resVal: number = 0; + for (let i = 0; i < length; i++) { + let leftMaxHeight: number = height[i], + rightMaxHeight: number = height[i]; + let leftIndex: number = i - 1, + rightIndex: number = i + 1; + while (leftIndex>= 0) { + if (height[leftIndex]> leftMaxHeight) + leftMaxHeight = height[leftIndex]; + leftIndex--; + } + while (rightIndex < length) { + if (height[rightIndex]> rightMaxHeight) + rightMaxHeight = height[rightIndex]; + rightIndex++; + } + resVal += Math.min(leftMaxHeight, rightMaxHeight) - height[i]; + } + return resVal; +}; +``` + +动态规划: + +```typescript +function trap(height: number[]): number { + const length: number = height.length; + const leftMaxHeightDp: number[] = [], + rightMaxHeightDp: number[] = []; + leftMaxHeightDp[0] = height[0]; + rightMaxHeightDp[length - 1] = height[length - 1]; + for (let i = 1; i < length; i++) { + leftMaxHeightDp[i] = Math.max(height[i], leftMaxHeightDp[i - 1]); + } + for (let i = length - 2; i>= 0; i--) { + rightMaxHeightDp[i] = Math.max(height[i], rightMaxHeightDp[i + 1]); + } + let resVal: number = 0; + for (let i = 0; i < length; i++) { + resVal += Math.min(leftMaxHeightDp[i], rightMaxHeightDp[i]) - height[i]; + } + return resVal; +}; +``` + +单调栈: + +```typescript +function trap(height: number[]): number { + const length: number = height.length; + const stack: number[] = []; + stack.push(0); + let resVal: number = 0; + for (let i = 1; i < length; i++) { + let top = stack[stack.length - 1]; + if (height[top]> height[i]) { + stack.push(i); + } else if (height[top] === height[i]) { + stack.pop(); + stack.push(i); + } else { + while (stack.length> 0 && height[top] < height[i]) { + let mid = stack.pop(); + if (stack.length> 0) { + let left = stack[stack.length - 1]; + let h = Math.min(height[left], height[i]) - height[mid]; + let w = i - left - 1; + resVal += h * w; + top = stack[stack.length - 1]; + } + } + stack.push(i); + } + } + return resVal; +}; +``` + ### C: 一种更简便的双指针方法: diff --git "a/problems/0084.346円237円261円347円212円266円345円233円276円344円270円255円346円234円200円345円244円247円347円232円204円347円237円251円345円275円242円.md" "b/problems/0084.346円237円261円347円212円266円345円233円276円344円270円255円346円234円200円345円244円247円347円232円204円347円237円251円345円275円242円.md" index 439a3bc5b7..8f10a58251 100644 --- "a/problems/0084.346円237円261円347円212円266円345円233円276円344円270円255円346円234円200円345円244円247円347円232円204円347円237円251円345円275円242円.md" +++ "b/problems/0084.346円237円261円347円212円266円345円233円276円344円270円255円346円234円200円345円244円247円347円232円204円347円237円251円345円275円242円.md" @@ -486,5 +486,95 @@ var largestRectangleArea = function(heights) { return maxArea; }; ``` +TypeScript: + +> 双指针法(会超时): + +```typescript +function largestRectangleArea(heights: number[]): number { + let resMax: number = 0; + for (let i = 0, length = heights.length; i < length; i++) { + // 左开右开 + let left: number = i - 1, + right: number = i + 1; + while (left>= 0 && heights[left]>= heights[i]) { + left--; + } + while (right < length && heights[right]>= heights[i]) { + right++; + } + resMax = Math.max(resMax, heights[i] * (right - left - 1)); + } + return resMax; +}; +``` + +> 动态规划预处理: + +```typescript +function largestRectangleArea(heights: number[]): number { + const length: number = heights.length; + const leftHeightDp: number[] = [], + rightHeightDp: number[] = []; + leftHeightDp[0] = -1; + rightHeightDp[length - 1] = length; + for (let i = 1; i < length; i++) { + let j = i - 1; + while (j>= 0 && heights[i] <= heights[j]) { + j = leftHeightDp[j]; + } + leftHeightDp[i] = j; + } + for (let i = length - 2; i>= 0; i--) { + let j = i + 1; + while (j < length && heights[i] <= heights[j]) { + j = rightHeightDp[j]; + } + rightHeightDp[i] = j; + } + let resMax: number = 0; + for (let i = 0; i < length; i++) { + let area = heights[i] * (rightHeightDp[i] - leftHeightDp[i] - 1); + resMax = Math.max(resMax, area); + } + return resMax; +}; +``` + +> 单调栈: + +```typescript +function largestRectangleArea(heights: number[]): number { + heights.push(0); + const length: number = heights.length; + // 栈底->栈顶:严格单调递增 + const stack: number[] = []; + stack.push(0); + let resMax: number = 0; + for (let i = 1; i < length; i++) { + let top = stack[stack.length - 1]; + if (heights[top] < heights[i]) { + stack.push(i); + } else if (heights[top] === heights[i]) { + stack.pop(); + stack.push(i); + } else { + while (stack.length> 0 && heights[top]> heights[i]) { + let mid = stack.pop(); + let left = stack.length> 0 ? stack[stack.length - 1] : -1; + let w = i - left - 1; + let h = heights[mid]; + resMax = Math.max(resMax, w * h); + top = stack[stack.length - 1]; + } + stack.push(i); + } + } + return resMax; +}; +``` + + + -----------------------