zoukankan      html  css  js  c++  java
  • 有n个数(两两不同),对于这n个数的每个连续子序列,把其中最大的一个数标记一次,问最后每个数被标记次数

    今天在qq群了看到了这个题目,觉得用单调栈的解法挺好,可以在o(n)内搞定,特意记录下来

    首先明确单调栈的含义:

    栈是FILO的,栈的所有操作都是在栈顶进行。

    单调性指的是当前栈中存储的元素是严格的递增或者递减。

    递增:栈中元素从栈顶到栈底是严格递增的; 递减:栈中元素从栈顶到栈底是严格递减的。

    举例:先后入栈的元素假设为9,3,10,1,15。。

    考虑递增栈:

    初始时,栈为空;

    9入栈,栈当前为(9)

    3入栈,栈不变

    10入栈,9出栈,栈当前为(10)

    1入栈,栈不变

    15入栈,10出栈,栈当前为(15)

    本题目解读:(群中出题者给的例子)

    举例:

    输入={1, 4, 2, 3}

    初始标记都是0={0, 0, 0, 0}

    取子区间[1, 4] 最大数是4 所以4做一次标记 标记变为{0, 1, 0, 0}

    子区间[1, 3] 最大数还是4 {0, 2, 0 ,0}

    [1, 2] {0, 3, 0, 0}

    ……

    这样遍历所有的n*(n-1)/2子区间之后 输出当前标记数组即可
     
    解题思路:依次遍历每个数,利用单调栈的思路,找到每个数前面第一个比它大的数,再找到后面第一个比它大的数。然后直接计算当前数对应的结果。。
    比如说:{5,1, 4, 2, 3,6}
    假设当前遍历到了数4,则前面第一个比它的是5,后面第一比它大的是6,显然,当某个子序列最大值为4时,这个子序列不能包含5和5前面的数,也不能包含6和6后面的数,所以直接考虑区间{1,4,2,3}中4能作为最大数的子序列个数count,count即为4对应的最后结果。
    计算公式:假设4前面数的个数为m(这些数均小于4),4后面的个数为n(这n个数均小于4),m和n可以由下标计算得到,于是有:
    (1)4不作为序列边界的序列数count1 = m * n;
    (2)4作为序列边界的序列数count2 = m + n;
    所以可知: count = count1+count2 = m*n+m+n;
     
    依次计算每个数的count值,即可在o(n)内解决这道题。
     
  • 相关阅读:
    Java中数组遍历
    数组常见异常
    数组的访问
    Java中数组的定义方式
    Java中数组的概念与特点
    node爬虫技术初探
    node相关内容
    vs code快捷键
    vue 入门开发
    es6 常见用法
  • 原文地址:https://www.cnblogs.com/xlzhh/p/4415731.html
Copyright © 2011-2022 走看看