Google interview question: count bounded slices(min/max queue)

Question:

A Slice of an array said to be a Bounded slice if Max(SliceArray)-Min(SliceArray)<=K.

If Array [3,5,6,7,3] and K=2 provided .. the number of bounded slice is 9,

first slice (0,0) in the array Min(0,0)=3 Max(0,0)=3 Max-Min<=K result 0<=2 so it is bounded slice

second slice (0,1) in the array Min(0,1)=3 Max(0,1)=5 Max-Min<=K result 2<=2 so it is bounded slice

second slice (0,2) in the array Min(0,1)=3 Max(0,2)=6 Max-Min<=K result 3<=2 so it is not bounded slice

in this way you can find that there are nine bounded slice.

(0, 0), (0, 1), (1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3), (4, 4).

直接的做法是对数组每个元素向右扫描,记录min/max,选择符合条件的slice作为结果,时间复杂度为O(N^2)。

我们发现对数组中index i的元素向右扫描到index j时不满足条件,那么以i为起点j之后的slice都不可能满足条件,因此需要右移i,相当于维护一个满足max-min<=k的滑动窗口。那么可以设计算法如下:(1) 创建一个min/max queue,要求push,pop,peek,getMax,getMin为常数时间。(2) 遍历数组,若当前元素不会导致队列内元素不满足条件时,push该元素;若当前元素会导致队列内元素不满足条件,则输出所有满足条件的结果(例如队列头index为2,当前index为5,则将(2,2),(2,3),(2,4)加入到结果中),pop队列头元素,再次检查当前元素能否入队列。这个算法的时间复杂度为O(N)。

那么如何实现我们所要求的min/max queue呢?我们知道只有队列头和队列尾是可以操作的(Java的Queue接口是LinkedList实现的,因此是可以用Iterator来遍历队列内部的元素,但若遍历队列求最大最小值,时间复杂度为O(N))。实现min/max queue之前,我们先看一下如何实现min/max stack。

https://leetcode.com/problems/min-stack/

leetcode的这道题展示了如何构建min/max stack。我们需要构建一个额外堆栈来记录最大值,和一个额外的堆栈来记录最小值。

class MinMaxStack{
    private Deque<Integer> stack = new LinkedList<>();
    private Deque<Integer> minStack = new LinkedList<>();
    private Deque<Integer> maxStack = new LinkedList<>();
    public void push(int x) {
        stack.push(x);
        if(minStack.isEmpty() || minStack.peek()>=x) minStack.push(x);
        if(maxStack.isEmpty() || maxStack.peek()<=x) maxStack.push(x);
    }
    public int pop() {
        int tmp = stack.pop();
        if(!minStack.isEmpty() && minStack.peek() == tmp) minStack.pop();
        if(!maxStack.isEmpty() && maxStack.peek() == tmp) maxStack.pop();
        return tmp;
    }
    public int peek() {
        return stack.peek();
    }
    public boolean isEmpty(){
        return stack.isEmpty();
    }
    public int getMin() {
        if(!minStack.isEmpty()) return minStack.peek();
        else return Integer.MAX_VALUE;
    }
    public int getMax(){
        if(!maxStack.isEmpty()) return maxStack.peek();
        else return Integer.MIN_VALUE;
    }
}

利用min/max stack,我们可以构建min/max queue。如何用stack来模拟queue?我们用两个stack来实现queue的操作。当queue执行offer操作时,我们将这个元素push到stack 1中,当queue执行poll操作时,若stack 2为空,我们将所有stack 1中的元素pop-push到stack 2中,然后再从stack 2中pop。可以看到模拟queue的offer/poll操作的均摊时间复杂度为O(1)。我们知道queueMax=max(stack1Max, stack2Max), queueMin=min(stack1Min, stack2Min)。

class MinMaxQueue{
    MinMaxStack stack1 = new MinMaxStack();
    MinMaxStack stack2 = new MinMaxStack();
    public void offer(int x){
        stack1.push(x);
    }
    public int poll(){
        if(!stack2.isEmpty()){
            return stack2.pop();
        }
        while(!stack1.isEmpty()){
            stack2.push(stack1.pop());
        }
        return stack2.pop();
    }
    public boolean isEmpty(){
        return stack1.isEmpty() && stack2.isEmpty();
    }
    public int getMin(){
        return Math.min(stack1.getMin(), stack2.getMin());
    }
    public int getMax(){
        return Math.max(stack1.getMax(), stack2.getMax());
    }
}
时间: 2024-08-05 19:45:53

Google interview question: count bounded slices(min/max queue)的相关文章

Google interview question: k-nearest neighbor (k-d tree)

Question: You are given information about hotels in a country/city. X and Y coordinates of each hotel are known. You need to suggest the list of nearest hotels to a user who is querying from a particular point (X and Y coordinates of the user are giv

Google interview question: quickSort-like questions

上一篇总结了mergeSort-like questions,这篇总结一下有关quickSort的问题. Question: Given an array of object A, and an array of object B. All A's have different sizes, and all B's have different sizes. Any object A is of the same size as exactly one object B. We have a f

Google interview question: disjoint-set questions

Question: Given a n,m which means the row and column of the 2D matrix and an array of pair A( size k). Originally, the 2D matrix is all 0 which means there is only sea in the matrix. The list pair has k operator and each operator has two integer A[i]

LINQ to SQL语句之Select/Distinct和Count/Sum/Min/Max/Avg (转)

Select/Distinct操作符 适用场景:o(∩_∩)o- 查询呗. 说明:和SQL命令中的select作用相似但位置不同,查询表达式中的select及所接子句是放在表达式最后并把子句中的变量也就是结果返回回来:延迟. Select/Distinct操作包括9种形式,分别为简单用法. 匿名类型形式.条件形式.指定类型形式.筛选形式.整形类型形式. 嵌套类型形式.本地方法调用形式.Distinct形式. 1.简单用法: 这个示例返回仅含客户联系人姓名的序列. var q = from c i

linqtosql(GroupBy/Having/Count/Sum/Min/Max/Avg操作符)

Group By/Having操作符 适用场景:分组数据,为我们查找数据缩小范围. 说明:分配并返回对传入参数进行分组操作后的可枚举对象.分组:延迟 1.简单形式:var q = from p in db.Products group p by p.CategoryID into g select g; 语句描述:使用Group By按CategoryID划分产品. 说明:from p in db.Products 表示从表中将产品对象取出来.group p by p.CategoryID in

LINQ to SQL语句(3)之Count/Sum/Min/Max/Avg

1.简单形式: 得到数据库中客户 的数量: var q = db.Customers.Count(); 2.带条件形 式: 得到数据库中未断货产品的数量: var q = db.Products.Count(p => !p.Discontinued); LongCount 说明 :返回集合中的元素个数,返回LONG类型:不延迟.对于元素个数较多的集合可 视情况可以选用LongCount来统计元素个数,它返回long类型,比较精确.生成 SQL语句为:SELECT COUNT_BIG(*) FRO

LINQ Count/Sum/Min/Max/Avg

参考:http://www.cnblogs.com/peida/archive/2008/08/11/1263384.html Count/Sum/Min/Max/Avg用于统计数据,比如统计一些数据的个数,求和,最小值,最大值,平均数. 1.Count:返回集合中的元素个数,返回INT类型:不延迟.生成SQL语句为:SELECT COUNT(*) FROM 描述:获得数据库中顾客的数量 语句: var q =                 ndc.Customers.Count(); 对应S

LINQ to SQL语句之Select/Distinct和Count/Sum/Min/Max/Avg

上一篇讲述了LINQ,顺便说了一下Where操作,这篇开始我们继续说LINQ to SQL语句,目的让大家从语句的角度了解LINQ,LINQ包括LINQ to Objects.LINQ to DataSets.LINQ to SQL.LINQ to Entities.LINQ to XML,但是相对来说LINQ to SQL在我们程序中使用最多,毕竟所有的数据都要在数据库运行着各种操作.所以先来学习LINQ to SQL,其它的都差不多了,那么就从Select说起吧,这个在编写程序中也最为常用.

LINQ to SQL Count/Sum/Min/Max/Avg Join

public class Linq { MXSICEDataContext Db = new MXSICEDataContext(); // LINQ to SQL // Count/Sum/Min/Max/Avg // Count public void Count() { // 说明:返回集合中的元素个数,返回 INT 类型:不延迟.生成 SQL 语句为: SELECT COUNT(*) FROM //简单形式 性能差 var count = Db.MXSMemeber.Count(); /