测试开发备战秋招面试10-牛客刷题之堆/栈/队列

努力了那么多年,回头一望,几乎全是漫长的挫折和煎熬。对于大多数人的一生来说,顺风顺水只是偶尔,挫折、不堪、焦虑和迷茫才是主旋律。我们登上并非我们所选择的舞台,演出并非我们所选择的剧本。继续加油吧!

目录

1、用两个栈实现队列

2、 包含min函数的栈

3、有效括号序列

4、滑动窗口的最大值

5、最小的K个数

6、寻找第K大

7、数据流中的中位数


1、用两个栈实现队列

题目链接:用两个栈实现队列_牛客题霸_牛客网

思路:元素全部入栈1,然后出栈入栈2,最后从栈2全部出栈。

Java版:

import java.util.Stack;

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
       stack1.push(node) ;
    }
    
    public int pop() {
        if(stack2.isEmpty()){
            while(!stack1.isEmpty()){
                stack2.add(stack1.pop()) ;
            }
        }
        return stack2.pop() ;
      
    }
}

2、 包含min函数的栈

题目链接:包含min函数的栈_牛客题霸_牛客网

思路:使用两个栈,一个栈用于维护入栈和出栈,取栈顶元素,另一个栈用于维护单调栈,也是取栈顶元素。

Java版:

import java.util.Stack;

public class Solution {

    Stack<Integer> s1 = new Stack<>() ;
    Stack<Integer> s2 = new Stack<>() ;

    public void push(int node) {
        s1.push(node) ;
        if(s2.isEmpty() || s2.peek() > node){
            s2.push(node) ;
        }else{
            s2.push(s2.peek()) ;
        }
    }
    
    public void pop() {
        s1.pop() ;
        s2.pop() ;
    }
    
    public int top() {
       return  s1.peek() ;
    }
    
    public int min() {
        return s2.peek() ;
    }
}

3、有效括号序列

题目链接:有效括号序列_牛客题霸_牛客网
思路:每次如果遇到左括号,就让右括号入栈,每次遇到右括号,出栈匹配。

Java版:
 

import java.util.*;


public class Solution {
    /**
     * 
     * @param s string字符串 
     * @return bool布尔型
     */
    public boolean isValid (String s) {
        // write code here
        Stack<Character> s1 = new Stack<>() ;
        for(int i=0; i<s.length(); i++){
            if(s.charAt(i) == '{'){
                s1.add('}') ;
            }else if(s.charAt(i) == '('){
                s1.add(')') ;
            }else if(s.charAt(i) == '['){
                s1.add(']') ;
            }else if(s1.isEmpty() || s1.pop() != s.charAt(i)){
                return false ;
            }
        }
        return s1.isEmpty() ;
    }
}

4、滑动窗口的最大值

题目链接:滑动窗口的最大值_牛客题霸_牛客网

思路:暴露枚举所有滑动窗口,依次比对所有窗口中值的大小即可。
暴力版:

import java.util.*;
public class Solution {
    public ArrayList<Integer> maxInWindows(int [] num, int size) {
        ArrayList<Integer> arrayList = new ArrayList<>() ;
        if(num.length == 0 || size > num.length || size == 0){
            return arrayList ;
        }
        for(int i=0; i<num.length-size+1; i++){
            int max = num[i] ;
            for(int j=i+1; j<i+size; j++){
                max = Math.max(max, num[j]) ;
            }
            arrayList.add(max) ;
        }
        return arrayList ;

    }
}

思路2:维护一个双端的单调队列,让每次后面入队的都比前面大,每一个新窗口,需要队列头部元素出队。

import java.util.*;
public class Solution {
    public ArrayList<Integer> maxInWindows(int [] num, int size) {
        //利用双端队列,每次尾部进入保证比之前的小,每次下一个窗口时,移除头部元素
        ArrayList<Integer> arrayList = new ArrayList<Integer>() ;
        ArrayDeque<Integer> arrayDeque = new ArrayDeque<Integer>() ;
        if(size==0 || num.length == 0 || size > num.length){
            return arrayList ;
        }
        for(int i=0; i<size; i++){
            while(!arrayDeque.isEmpty() && num[arrayDeque.getLast()] < num[i]){
                arrayDeque.pollLast() ;
            }
            arrayDeque.addLast(i) ;
        }

        for(int i=size; i<num.length; i++){
            arrayList.add(num[arrayDeque.peekFirst()]) ;
            while(!arrayDeque.isEmpty() && num[arrayDeque.getLast()] < num[i]){
                arrayDeque.pollLast() ;
            }
            while(!arrayDeque.isEmpty() &&  (i-size+1) > arrayDeque.peekFirst()){
                arrayDeque.pollFirst() ;
            }
            arrayDeque.addLast(i) ;
        }
        arrayList.add(num[arrayDeque.peekFirst()]) ;
        return arrayList ;

    }
}

5、最小的K个数

题目链接:最小的K个数_牛客题霸_牛客网

思路:直接排序法。
Java版:

import java.util.*;

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        //直接排序法
        ArrayList<Integer> arr = new ArrayList<>() ;
        Arrays.sort(input) ;
        for(int i=0; i<k; i++){
            arr.add(input[i]) ;
        }
        return arr ;
    }
}

思路2:建立容量为k的大根堆,每次对比堆顶元素,如果当前元素小于堆顶元素,则替换。

import java.util.*;

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        //堆排序法,建立容量为k的优先队列构成的大根堆
       
        ArrayList<Integer> list = new ArrayList<>() ;
         if(input.length == 0 || k == 0){
            return list ;
         }
        PriorityQueue<Integer> queue = new PriorityQueue<>((o1,o2)->o2-o1) ;
        for(int i=0; i<input.length; i++){
            if(queue.size() < k){
                queue.add(input[i]) ;
            }else{
                if(input[i] < queue.peek()){
                    queue.poll() ;
                    queue.add(input[i]) ;
                }
            }
        }
        while(!queue.isEmpty()){
            list.add(queue.peek()) ;
            queue.poll() ;
        }
        return list ;
    }
}

6、寻找第K大

题目链接:寻找第K大_牛客题霸_牛客网

思路:直接排序,然后返回倒数第K个就行了。

Java版:

import java.util.*;

public class Solution {
    public int findKth(int[] a, int n, int K) {
        // write code here
        Arrays.sort(a) ;
        return a[n - K] ;
    }
}

7、数据流中的中位数

题目链接:数据流中的中位数_牛客题霸_牛客网

思路:先排序,然后取中位数即可。

Java版:


import java.util.* ;

public class Solution {
    ArrayList<Integer> arrayList = new ArrayList<>() ;
    public void Insert(Integer num) {
        arrayList.add(num) ;
        Collections.sort(arrayList) ;
    }

    public Double GetMedian() {
        int n = arrayList.size() ;
        double result = (n%2==1)  ? (double)arrayList.get(n/2) : (double)(arrayList.get(n/2) + arrayList.get(n/2-1)) / 2 ;  
        return result ;
    }
}

猜你喜欢

转载自blog.csdn.net/nuist_NJUPT/article/details/130693258