テスト開発 秋採用面接の準備 牛柯のブラッシング質問 10 個の山/スタック/キュー

何年も努力して振り返ってみると、ほとんどすべてが長い挫折と苦しみでした。ほとんどの人の人生において、順風満帆な時期はたまにしかなく、挫折、耐えられない、不安、混乱が主なテーマです。私たちは選ばなかった舞台に立ち、選ばなかった脚本を演じる。立ち止まるな!

目次

1. 2 つのスタックを持つキューを実装する

2. min 関数を含むスタック

3. 有効な括弧のシーケンス

4. スライディングウィンドウの最大値

5. K の最小数

6. K 番目に大きいものを見つける

7. データストリームの中央値


1. 2 つのスタックを持つキューを実装する

トピックリンク: 2 つのスタックを使用したキューの実装

アイデア: すべての要素はスタック 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 Function_Niu Ke Topic_Niu Ke を含むスタック。

アイデア: 2 つのスタックを使用します。1 つのスタックはプッシュとポップを維持するために使用され、スタックの最上位要素が取得され、もう 1 つのスタックはスタックの最上位要素でもある単調スタックを維持するために使用されます。

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. 有効な括弧のシーケンス

トピックリンク:効果的な括弧シーケンス_Niuke题目霸_Niuke.com
アイデア: 左括弧に遭遇するたびに、右括弧をスタックにプッシュし、右括弧に遭遇するたびに、それをスタックから取り出して一致させます。

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_Niuke Question Master_Niuke.com の最小数

アイデア: 直接選別方法。
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 番目の Big_Niuke を見つける Topic_Niuke.com

アイデア: 直接ソートし、下から 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