题目
题目链接:
https://www.nowcoder.com/practice/a7401d0dd4ec4071a31fd434e150bcc2
思路
单调栈解决的问题单调栈解决的问题是在一个数组中想知道所有数中,
左边离他近的比他大的和右边离他近的比他大的数
思考的问题:如果知道所有数上得到上述要求,
同时复杂度满足O(N)。单调栈结构:单调栈内,从栈底到栈顶满足从大到小。
例如:5(0)4(1)3(2)6(3)后面括号代表所属位置原文链接:https://blog.csdn.net/qq_35065720/article/details/104211981
参考答案Java
import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param nums int整型一维数组* @return int整型*/public int sumSubarr (ArrayList<Integer> ll) {int[] nums = new int[ll.size()];for (int i=0;i<ll.size();i++){nums[i] = ll.get(i);}//力扣同一道题://https://leetcode.cn/problems/sum-of-subarray-minimums/description/?utm_source=LCUS&utm_medium=ip_redirect&utm_campaign=transfer2china//单调栈int[] left = left(nums);int[] right = right(nums);long max = 0;for (int i = 0; i <nums.length ; i++) {//max +=nums[i]*(right[i]-left[i]+1);// max +=nums[i]*(right[i]-left[i]+1);int start = i-left[i];int end = right[i]-i;max+= start*end*(long)nums[i];max%=1000000007;}return (int) max;}public int[] left(int[] arr){//往左扩int n= arr.length;int[] ans = new int[n];Stack<Integer> stk = new Stack<>();for (int i = n-1; i >=0 ; i--) {while (!stk.isEmpty() && arr[stk.peek()] >= arr[i]){ans[stk.pop()] = i;}stk.add(i);}while (!stk.isEmpty()){ans[stk.pop()] = -1;}return ans;}public int[] right(int[] arr){ //往右扩int n = arr.length;int[] ans = new int[n];Stack<Integer> stk = new Stack<>();for (int i = 0; i <n ; i++) {while (!stk.isEmpty() && arr[stk.peek()] > arr[i]){ans[stk.pop()] = i;}stk.add(i);}while (!stk.isEmpty()){ans[stk.pop()] = n;}return ans;}
}
参考答案Go
package main/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param nums int整型一维数组 * @return int整型
*/
func sumSubarr( nums []int ) int {//单调栈n := len(nums)left := left(nums)right := right(nums)ans := 0for i := 0; i < n; i++ {start := i - left[i]end := right[i] - ians += start * end * nums[i]ans %= 1000000007}return ans
}func left(arr []int) []int { //往左扩n := len(arr)ans := make([]int, n)stk := []int{}for i := n - 1; i >= 0; i-- {for len(stk) > 0 && arr[stk[len(stk)-1]] >= arr[i] {ans[stk[len(stk)-1]] = istk = stk[:len(stk)-1]}stk = append(stk, i)}for len(stk) != 0 {ans[stk[len(stk)-1]] = -1stk = stk[:len(stk)-1]}return ans
}func right(arr []int) []int { //往右扩n := len(arr)ans := make([]int, n)stk := []int{}for i := 0; i < n; i++ {for len(stk) != 0 && arr[stk[len(stk)-1]] > arr[i] {ans[stk[len(stk)-1]] = istk = stk[:len(stk)-1]}stk = append(stk, i)}for len(stk) != 0 {ans[stk[len(stk)-1]] = nstk = stk[:len(stk)-1]}return ans
}
参考答案PHP
<?php/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param nums int整型一维数组 * @return int整型*/
function sumSubarr( $nums )
{//单调栈$n = count($nums);$left = left($nums);$right = right($nums);$ans = 0;for($i=0;$i<$n;$i++){$start = $i-$left[$i];$end = $right[$i]-$i;$ans += $start*$end*$nums[$i];$ans %=1000000007;}return $ans;
}function left($arr){$n = count($arr);$ans = [];$s =[];for($i=$n-1;$i>=0;$i--){while ( count($s)!=0 && $arr[$s[count($s)-1]] >= $arr[$i]){$ans[array_pop($s)] = $i;}array_push($s,$i);}while ( count($s)!=0){$ans[array_pop($s)] = -1;}return $ans;
}function right($arr){$n = count($arr);$ans = [];$s =[];for($i=0;$i<$n;$i++){while ( count($s)!=0 && $arr[$s[ count($s)-1]] > $arr[$i]){$ans[array_pop($s)] = $i;}array_push($s,$i);}while ( count($s)!=0){$ans[array_pop($s)] = $n;}return $ans;
}