当前位置: 首页 > news >正文

效果图制作合同范本哈尔滨seo服务

效果图制作合同范本,哈尔滨seo服务,网站开发投标文件服务承诺部分,网站建设制作设计公司哪家好单调栈:就是在栈中实现数据的单调性。即从栈底到栈顶,要么递增,要么递减。 那么,使用单调栈,可以解决什么问题呢? 给定一个可能含有重复值的数组arr,i位置的数一定存在如下两个信息 1&#x…

单调栈:就是在栈中实现数据的单调性。即从栈底到栈顶,要么递增,要么递减。

那么,使用单调栈,可以解决什么问题呢?

给定一个可能含有重复值的数组arr,i位置的数一定存在如下两个信息

1)arr[i]的左侧离i最近并且小于(或者大于)arr[i]的数在哪?

2)arr[i]的右侧离i最近并且小于(或者大于)arr[i]的数在哪? 如果想得到arr中所有位置的两个信息,怎么能让得到信息的过程尽量快

题目一:给定一个一维数组,数据都为正整数并且无重复值,要求设计一个O(N)时间复杂度的算法,找出任意位置的数据,左侧小于当前位置最近的数在哪,右侧小于当前数最近的的数在哪?

假设: 这个数组是 {1,3,5,4}。栈的单调性从栈底到栈顶递增。

那么如下:

5
3
1

也就是说,前3个数符合预期的栈的单调性,可以正常的放入栈中。那么,当最后一个数据4想要放入栈中的时候,发现栈顶元素为5,比自己大。直接放入就破坏了栈的单调性了。

1. 我们需要把栈顶元素5弹出,这5就知道右侧小于自己的并且距离最近的数为4,而左侧离自己最近并且小于自己的数为3.

2. 此时,栈顶元素为3,小于4. 那么4直接放入栈顶。整个数组全部结束

4
3
1

3. 栈循环弹出,4是最后一个元素,并且栈具有单调性。因此,弹出4可以知道,左侧离自己最近的数为3. 而右侧没有比自己更小的数

4. 弹出3,左侧比自己小的数是1,而右侧没有比自己小的数

5. 弹出1,此时栈空了。左侧、右侧都没有小于自己的数。

以上一切,只是为了直观的体现栈整个操作流程。而实际的算法设计肯定是不能用数据来直接使用的,而是需要使用每个数据对应的位置,即下标

//无重复元素public int[][] dp(int[] arr){if(arr == null || arr.length == 0) {return null;}int[][] dp = new int[arr.length][arr.length];Stack<Integer> stack = new Stack<>();for (int i = 0; i < arr.length; i++){while (!stack.isEmpty() && arr[stack.peek()] > arr[i]){int cur = stack.pop();// -1代表不存在左侧比cur下标对应的值更小的值int leftIndex = stack.isEmpty() ? -1 : stack.peek();dp[cur][0] = leftIndex;dp[cur][1] = i;}//放入下标stack.push(i);}//栈中剩余元素,保持单调增while (!stack.isEmpty()) {int cur = stack.pop();// -1代表不存在左侧比cur下标对应的值更小的值int leftIndex = stack.isEmpty() ? -1 : stack.peek();dp[cur][0] = leftIndex;//因为单调增、所有右侧不存在比自己还小的值了dp[cur][1] = -1;}return dp;}

题目二:数组存在重复元素,设计一个栈,要求能够快速找到任意位置左、右侧比自己小、位置最近的数据。

public static int[][] getNearLess(int[] arr) {int[][] res = new int[arr.length][2];Stack<List<Integer>> stack = new Stack<>();for (int i = 0; i < arr.length; i++) { // i -> arr[i] 进栈while (!stack.isEmpty() && arr[stack.peek().get(0)] > arr[i]) {List<Integer> popIs = stack.pop();int leftLessIndex = stack.isEmpty() ? -1 : stack.peek().get(stack.peek().size() - 1);for (Integer popi : popIs) {res[popi][0] = leftLessIndex;res[popi][1] = i;}}if (!stack.isEmpty() && arr[stack.peek().get(0)] == arr[i]) {stack.peek().add(Integer.valueOf(i));} else {ArrayList<Integer> list = new ArrayList<>();list.add(i);stack.push(list);}}while (!stack.isEmpty()) {List<Integer> popIs = stack.pop();int leftLessIndex = stack.isEmpty() ? -1 : stack.peek().get(stack.peek().size() - 1);for (Integer popi : popIs) {res[popi][0] = leftLessIndex;res[popi][1] = -1;}}return res;}

题目三:力扣1856. 子数组最小乘积的最大值

https://leetcode.cn/problems/maximum-subarray-min-product/description/

题目详情直接打开连接进行查看,这里直接说解题思路。

1. 给定数组,就存在子数组,并且子数组是连续的

2.子数组中肯定是存在最小值的,也必然会知道子数组累加和。

3. 假设每个数都是最小值,这样就能利用单调栈结构找到左侧、右侧比自己小的位置。那么除了这两个位置以外,中间部分的数据就是自己最小了。利用这个思想,我们来实现代码

数据1354
下标0123
累加和14913

5左侧比自己小的数据为3,对应下标为1;

5右侧比自己小的数据为4,对应下标为3;

也就是说5这个数据想要做最小值,那么下标1到3之间,并且不能包含下标1和下标3的和。

既然不能包含到下标为3的位置,变相的也就是能够包含到下标为2的位置,即累加和为 9 - 4 = 5;

那子数组累加和 * 最小值 =  5 * 5 = 25;

其他的依次类推........

package code04.单调栈_01;import java.util.Stack;/*** 1856. 子数组最小乘积的最大值* https://leetcode.cn/problems/maximum-subarray-min-product/description/*/
public class Code01_MinSumOfSubArr {public int maxSumMinProduct(int[] nums){if (nums == null || nums.length == 0) {return 0;}int size = nums.length;//前缀和数组。 题目规定要使用64位有符号整数保存long[] dp = new long[size];dp[0] = nums[0];for (int i = 1; i < size; i++) {dp[i] = dp[i-1] + nums[i];}long ans = Long.MIN_VALUE;//[0 ......)Stack<Integer> stack = new Stack();for(int i = 0; i < size; i++){while (!stack.isEmpty()&& nums[stack.peek()] >= nums[i]) {//当前正在处理的数下标int cur = stack.pop();long sum = stack.isEmpty() ? dp[i-1] : dp[i-1] - dp[stack.peek()];ans = Math.max(ans, sum * nums[cur]);}//放入下标stack.push(i);}//右侧值越来越大while (!stack.isEmpty()) {//当前正在处理的数下标int cur = stack.pop();long sum = stack.isEmpty() ? dp[size-1] : (dp[size-1] - dp[stack.peek()]);ans = Math.max(ans, sum * nums[cur]);}return (int) (ans % 1000000007);}public static void main(String[] args){int[] nums = {3,1,5,6,4,2};Code01_MinSumOfSubArr test = new Code01_MinSumOfSubArr();System.out.println(test.maxSumMinProduct(nums));}
}

此处可能会有疑问,此处使用的是无重复元素构造单调栈的算法,这一题不需要考虑重复元素的情况吗?举个例子,假如数组为 {1,2,3,2}

栈中放入1,2 3.  当放入最后一个2的时候,会把栈中的3和2弹出,并且把最后一个2入栈。 而最后一个2右侧没有比他小的值,左侧比他小的值为1,对应的下标为0. 也就是说从下标0到最后一个2的位置,此时最后一个2是最小值。当然,下标0处的1是不包含在内的。

也就是说,重复元素具有连通性,很多时候是不需要考虑重复元素的情况的。

http://www.hkea.cn/news/406658/

相关文章:

  • 国外建设工程招聘信息网站tool站长工具
  • 专业做相册书的网站电商网站建设制作
  • 银川网站开发公司电话东莞网
  • 环境保护局网站管理制度建设百度指数的主要功能有
  • 安装wordpress提示500错误关键词优化的策略有哪些
  • 企业网站建设公司排名深圳高端seo公司助力企业
  • 做网站套餐网站seo
  • 网站上的代码网页怎么做的下载百度软件
  • 网站功能模块建设搜狗推广
  • 网站做推广有用吗网站页面设计
  • 做简报的网站广州搜发网络科技有限公司
  • 南乐县住房和城乡建设局网站制作网站的步骤是什么
  • 金华做网站最专业的公司搜易网提供的技术服务
  • wordpress适合门户网站吗怎么营销自己的产品
  • 常用的网站类型有哪些seo优化专员编辑
  • 网站专题框架怎么做海阳seo排名
  • 手机网站代码下载黄页网站推广服务
  • 做网站前端多少钱在线bt种子
  • wordpress+模版+推荐专业网站seo推广
  • 浦项建设公司员工网站2023免费推广入口
  • 如何查询某个网站的设计公司最新推广注册app拿佣金
  • 八宝山做网站公司打广告
  • wordpress vip查看插件南宁seo费用服务
  • 建站之星模板怎么设置手机如何做网站
  • 上海公司网站制作价格西安百度关键词排名服务
  • 长沙网页制作开发公司aso优化方案
  • 深圳罗湖网站制作成人电脑基础培训班
  • 无锡网站制作咨询深圳网站设计十年乐云seo
  • 大连城市建设网站seo优化顾问服务阿亮
  • 福州 网站建设沈阳seo关键词排名优化软件