首页 > 其他分享 >[左神面试指南] 栈和队列篇

[左神面试指南] 栈和队列篇

时间:2023-11-07 16:13:14浏览次数:26  
标签:arr 队列 incStack 左神 面试 int isEmpty new public

CD5 设计一个有 getMin 功能的栈

/*
 * 维护一个最小栈minStack
 * dataStack每压入一个数, minStack也压入一个当前状态的最小值
 */
public class CD5_1
{
    public static class Solution
    {
        public Stack<Integer> dataStack = new Stack<>();
        public Stack<Integer> minStack = new Stack<>();

        public void push(int data)
        {
            dataStack.push(data);
            if (minStack.isEmpty()) minStack.push(data);
            else minStack.push(Math.min(minStack.peek(), data));
        }

        public void pop()
        {
            dataStack.pop();
            minStack.pop();
        }

        public int getMin()
        {
            return minStack.peek();
        }
    }

    public static void main(String[] args)
    {
        Solution solution = new Solution();
        Scanner in = new Scanner(System.in);
        int N = Integer.parseInt(in.nextLine());
        while (N-- > 0)
        {
            String s = in.nextLine();
            if (s.startsWith("push"))
                solution.push(Integer.parseInt(s.split(" ")[1]));
            else if (s.startsWith("pop"))
                solution.pop();
            else
                System.out.println(solution.getMin());
        }
    }
}

/*
 * 维护一个最小栈minStack
 * dataStack压入一个数data时, 当data<=minStack.peek()时, minStack才压入
 */
public class CD5_2
{
    public static class Solution
    {
        public Stack<Integer> dataStack = new Stack<>();
        public Stack<Integer> minStack = new Stack<>();

        public void push(int data)
        {
            dataStack.push(data);
            if (minStack.isEmpty()) minStack.push(data);
            else if (data <= minStack.peek()) minStack.push(data);
        }

        public void pop()
        {
            if (dataStack.peek().equals(minStack.peek())) minStack.pop();
            dataStack.pop();
        }

        public int getMin()
        {
            return minStack.peek();
        }
    }

    public static void main(String[] args)
    {
        Solution solution = new Solution();
        Scanner in = new Scanner(System.in);
        int N = Integer.parseInt(in.nextLine());
        while (N-- > 0)
        {
            String s = in.nextLine();
            if (s.startsWith("push"))
                solution.push(Integer.parseInt(s.split(" ")[1]));
            else if (s.startsWith("pop"))
                solution.pop();
            else
                System.out.println(solution.getMin());
        }
    }
}

CD6 由两个栈组成的队列

/* 模拟 */
public class CD6_1
{
    public static class Solution
    {
        public Stack<Integer> stack1 = new Stack<>();
        public Stack<Integer> stack2 = new Stack<>();

        public void add(int data)
        {
            stack1.add(data);
        }

        public void poll()
        {
            if (stack2.isEmpty())
            {
                while (!stack1.isEmpty())
                    stack2.add(stack1.pop());
            }
            stack2.pop();
        }

        public int peek()
        {
            if (stack2.isEmpty())
            {
                while (!stack1.isEmpty())
                    stack2.add(stack1.pop());
            }
            return stack2.peek();
        }
    }

    public static void main(String[] args)
    {
        Solution solution = new Solution();
        Scanner in = new Scanner(System.in);
        int N = Integer.parseInt(in.nextLine());
        while (N-- > 0)
        {
            String s = in.nextLine();
            if (s.startsWith("add"))
                solution.add(Integer.parseInt(s.split(" ")[1]));
            else if (s.startsWith("poll"))
                solution.poll();
            else
                System.out.println(solution.peek());
        }
    }
}

CD7 如何仅用递归函数和栈操作逆序一个栈

/* 模拟 */
public class CD7_1
{
    public static void solution(Stack<Integer> stack)
    {
        if (stack.isEmpty()) return;
        String prefix = stack.size() == 1 ? "" : " ";
        Integer popNum = stack.pop();
        solution(stack);
        System.out.print(prefix + popNum);
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        Stack<Integer> stack = new Stack<>();
        int N = Integer.parseInt(in.nextLine());
        while (N-- > 0)
            stack.add(in.nextInt());
        solution(stack);
    }
}

/* 模拟 */
public class CD7_2
{
    // 取栈底元素并将其删除
    public static int getAndRemoveLast(Stack<Integer> stack)
    {
        if (stack.size() == 1) return stack.pop();
        Integer popNum = stack.pop();
        int last = getAndRemoveLast(stack);
        stack.add(popNum);
        return last;
    }

    public static Stack<Integer> solution(Stack<Integer> stack)
    {
        if (stack.isEmpty()) return stack;
        int last = getAndRemoveLast(stack);
        Stack<Integer> ans = solution(stack);
        ans.add(last);
        return ans;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        Stack<Integer> stack = new Stack<>();
        int N = Integer.parseInt(in.nextLine());
        while (N-- > 0)
            stack.add(in.nextInt());
        Stack<Integer> res = solution(stack);
        while (!res.isEmpty())
            System.out.print(res.pop() + (res.isEmpty() ? "" : " "));
    }
}

CD100 猫狗队列⭐

/* ⭐利用时间戳⭐ */
public class CD100_1
{
    // 防止运行超时
    public static PrintWriter out = new PrintWriter(System.out);

    public static class Solution
    {
        public static Queue<int[]> catQue = new LinkedList<>();
        public static Queue<int[]> dogQue = new LinkedList<>();
        public static int time = 0;

        public void add(String name, int id)
        {
            if ("cat".equals(name))
                catQue.add(new int[]{time++, id});
            else if ("dog".equals(name))
                dogQue.add(new int[]{time++, id});
        }

        public void pollAll()
        {
            while (!catQue.isEmpty() && !dogQue.isEmpty())
            {
                if (catQue.peek()[0] < dogQue.peek()[0])
                    out.println("cat " + catQue.poll()[1]);
                else
                    out.println("dog " + dogQue.poll()[1]);
            }
            while (!dogQue.isEmpty())
                out.println("dog " + dogQue.poll()[1]);
            while (!catQue.isEmpty())
                out.println("cat " + catQue.poll()[1]);
        }

        public void pollDog()
        {
            while (!dogQue.isEmpty())
                out.println("dog " + dogQue.poll()[1]);
        }

        public void pollCat()
        {
            while (!catQue.isEmpty())
                out.println("cat " + catQue.poll()[1]);
        }

        public String isEmpty()
        {
            return (dogQue.isEmpty() && catQue.isEmpty()) ? "yes" : "no";
        }

        public String isDogEmpty()
        {
            return dogQue.isEmpty() ? "yes" : "no";
        }

        public String isCatEmpty()
        {
            return catQue.isEmpty() ? "yes" : "no";
        }
    }

    public static void main(String[] args)
    {
        Solution solution = new Solution();
        Scanner in = new Scanner(System.in);
        int N = Integer.parseInt(in.nextLine());
        while (N-- > 0)
        {
            String[] s = in.nextLine().split(" ");
            switch (s[0])
            {
                case "add":
                    solution.add(s[1], Integer.parseInt(s[2]));
                    break;
                case "pollAll":
                    solution.pollAll();
                    break;
                case "pollDog":
                    solution.pollDog();
                    break;
                case "pollCat":
                    solution.pollCat();
                    break;
                case "isEmpty":
                    out.println(solution.isEmpty());
                    break;
                case "isDogEmpty":
                    out.println(solution.isDogEmpty());
                    break;
                case "isCatEmpty":
                    out.println(solution.isCatEmpty());
                    break;
            }
        }
        out.flush();
    }
}

CD13 用一个栈实现另一个栈的排序

/* 模拟 */
public class CD13_1
{
    public static Stack<Integer> solution(Stack<Integer> stack)
    {
        Stack<Integer> temp = new Stack<>();
        while (!stack.isEmpty())
        {
            if (temp.isEmpty() || stack.peek() <= temp.peek())
                temp.add(stack.pop());
            else
            {
                Integer popNum = stack.pop();
                while (!temp.isEmpty() && popNum > temp.peek())
                    stack.add(temp.pop());
                temp.add(popNum);
            }
        }
        while (!temp.isEmpty())
            stack.add(temp.pop());
        return stack;
    }

    public static void main(String[] args)
    {
        Stack<Integer> stack = new Stack<>();
        Scanner in = new Scanner(System.in);
        int N = Integer.parseInt(in.nextLine());
        while (N-- > 0)
            stack.add(in.nextInt());
        Stack<Integer> res = solution(stack);
        while (!res.isEmpty())
            System.out.print(res.pop() + (res.isEmpty() ? "" : " "));
    }
}

CD22 用栈来求解汉诺塔问题⭐

/*
* ⭐递归⭐
* 1. 前n-1个盘子从左柱到右柱
* 2. 第n个盘子从左柱到临时柱
* 3. 前n-1个盘子从右柱到左柱
* 4. 第n个盘子从临时柱到右柱
* 5. 前n-1个盘子从左柱到右柱
*/
public class CD22_1
{
    public static int solution(int n, String left, String right, String temp)
    {
        if (n == 0) return 0;
        int p1 = solution(n - 1, left, right, temp);
        System.out.printf("Move %d from %s to %s\n", n, left, temp);
        int p2 = solution(n - 1, right, left, temp);
        System.out.printf("Move %d from %s to %s\n", n, temp, right);
        int p3 = solution(n - 1, left, right, temp);
        return p1 + p2 + p3 + 2;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        System.out.printf("It will move %d steps.", solution(n, "left", "right", "mid"));
    }
}

/* 非递归写法 */
public class CD22_2
{
}

CD15 生成窗口最大值数组

/* 单调递减队列 + 滑动窗口 */
public class CD15_1
{
    public static ArrayList<Integer> solution(int[] arr, int N, int W)
    {
        ArrayList<Integer> ans = new ArrayList<>();
        Deque<Integer> que = new LinkedList<>();
        int l = 0, r = 0;
        while (r < N)
        {
            while (r - l < W)
            {
                while (!que.isEmpty() && arr[r] > arr[que.getLast()])
                    que.removeLast();
                que.add(r);
                r++;
            }
            ans.add(arr[que.getFirst()]);
            l++;
            if (l > que.getFirst())
                que.removeFirst();
        }
        return ans;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, W;
        N = in.nextInt();
        W = in.nextInt();
        int[] arr = new int[N];
        for (int i = 0; i < N; i++)
            arr[i] = in.nextInt();
        ArrayList<Integer> res = solution(arr, N, W);
        System.out.println(res.stream().map(e -> String.valueOf(e)).collect(Collectors.joining(" ")));
    }
}

CD101 单调栈结构

/* 单调栈(无法处理数组中有相同数值的情况) */
public class CD101_1
{
    public static int[][] solution(ArrayList<Integer> arr)
    {
        Stack<Integer> incStack = new Stack<>();
        int[][] ans = new int[arr.size()][2];
        for (int idx = 0; idx < arr.size(); idx++)
        {
            while (!incStack.isEmpty() && arr.get(idx) < arr.get(incStack.peek()))
            {
                int popIdx = incStack.pop();
                ans[popIdx][0] = incStack.isEmpty() ? -1 : incStack.peek();
                ans[popIdx][1] = idx;
            }
            incStack.add(idx);
        }
        while (!incStack.isEmpty())
        {
            int popIdx = incStack.pop();
            ans[popIdx][0] = incStack.isEmpty() ? -1 : incStack.peek();
            ans[popIdx][1] = -1;
        }
        return ans;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out); // 防止运行超时
        ArrayList<Integer> arr = new ArrayList<>();
        int N = in.nextInt();
        while (N-- > 0)
            arr.add(in.nextInt());
        int[][] res = solution(arr);
        for (int[] temp : res)
            out.println(temp[0] + " " + temp[1]);
        out.flush();
    }
}

CD188 单调栈结构(进阶)⭐

/* ⭐单调栈(解决CD101的问题)⭐ */
public class CD188_1
{
    public static int[][] solution(ArrayList<Integer> arr)
    {
        Stack<Integer> incStack = new Stack<>();
        ArrayList<Integer> temp = new ArrayList<>();
        int[][] ans = new int[arr.size()][2];
        for (int idx = 0; idx < arr.size(); idx++)
        {
            while (!incStack.isEmpty() && arr.get(idx) < arr.get(incStack.peek()))
            {
                int popIdx = incStack.pop();
                temp.clear();
                temp.add(popIdx);
                while (!incStack.isEmpty() && arr.get(popIdx).equals(arr.get(incStack.peek())))
                    temp.add(incStack.pop());
                for (int i : temp)
                {
                    ans[i][0] = incStack.isEmpty() ? -1 : incStack.peek();
                    ans[i][1] = idx;
                }
            }
            incStack.add(idx);
        }
        while (!incStack.isEmpty())
        {
            int popIdx = incStack.pop();
            temp.clear();
            temp.add(popIdx);
            while (!incStack.isEmpty() && arr.get(popIdx).equals(arr.get(incStack.peek())))
                temp.add(incStack.pop());
            for (int i : temp)
            {
                ans[i][0] = incStack.isEmpty() ? -1 : incStack.peek();
                ans[i][1] = -1;
            }
        }
        return ans;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out); // 防止运行超时
        ArrayList<Integer> arr = new ArrayList<>();
        int N = in.nextInt();
        while (N-- > 0)
            arr.add(in.nextInt());
        int[][] res = solution(arr);
        for (int[] temp : res)
            out.println(temp[0] + " " + temp[1]);
        out.flush();
    }
}

CD16 求最大子矩阵的大小⭐

/* ⭐单调栈⭐ */
public class CD16_1
{
    public static int solution(int[][] arr)
    {
        int ans = Integer.MIN_VALUE;
        int[] height = new int[arr[0].length];
        for (int[] ints : arr)
        {
            for (int i = 0; i < arr[0].length; i++)
                height[i] = ints[i] == 1 ? height[i] + 1 : 0;
            ans = Math.max(ans, calMaxRec(height));
        }
        return ans;
    }

    public static int calMaxRec(int[] height)
    {
        int ans = Integer.MIN_VALUE, width;
        Stack<Integer> incStack = new Stack<>();
        for (int i = 0; i < height.length; i++)
        {
            while (!incStack.isEmpty() && height[i] < height[incStack.peek()])
            {
                int popIdx = incStack.pop();
                while (!incStack.isEmpty() && height[popIdx] == height[incStack.peek()])
                    incStack.pop();
                width = (i - 1) - (incStack.isEmpty() ? 0 : incStack.peek() + 1) + 1;
                ans = Math.max(ans, height[popIdx] * width);
            }
            incStack.add(i);
        }
        while (!incStack.isEmpty())
        {
            Integer popIdx = incStack.pop();
            width = (height.length - 1) - (incStack.isEmpty() ? 0 : incStack.peek() + 1) + 1;
            ans = Math.max(ans, height[popIdx] * width);
        }
        return ans;
    }

    public static void main(String[] args)
    {
        int N, M;
        Scanner in = new Scanner(System.in);
        N = in.nextInt();
        M = in.nextInt();
        int[][] arr = new int[N][M];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < M; j++)
                arr[i][j] = in.nextInt();
        System.out.println(solution(arr));
    }
}

CD18 最大值减去最小值小于或等于 num 的子数组数量⭐

/*
 * ⭐单调队列⭐
 * 若a[i...j]符合要求, 那么a[i...l]都符合要求(i<=l<=j)
 * 若a[i...j]不符合要求, 那么a[i...l]都不符合要求(l>j)
 */
public class CD18_1
{
    public static int solution(int[] arr, int NUM)
    {
        int len = arr.length, i = 0, j = 0, ans = 0;
        Deque<Integer> incStack = new LinkedList<>();
        Deque<Integer> decStack = new LinkedList<>();
        while (i < len)
        {
            while (j < len)
            {
                while (!incStack.isEmpty() && arr[j] <= arr[incStack.getLast()])
                    incStack.removeLast();
                incStack.addLast(j);
                while (!decStack.isEmpty() && arr[j] >= arr[decStack.getLast()])
                    decStack.removeLast();
                decStack.addLast(j);
                if (arr[decStack.getFirst()] - arr[incStack.getFirst()] > NUM)
                    break;
                j++;
            }
            ans += j - i;
            if (i == incStack.peekFirst()) incStack.removeFirst();
            if (i == decStack.peekFirst()) decStack.removeFirst();
            i++;
        }
        return ans;
    }

    public static void main(String[] args)
    {
        int N, NUM;
        Scanner in = new Scanner(System.in);
        N = in.nextInt();
        NUM = in.nextInt();
        int[] arr = new int[N];
        for (int i = 0; i < N; i++)
            arr[i] = in.nextInt();
        System.out.println(solution(arr, NUM));
    }
}

CD102 可见的山峰对数量❗

/* ❗思维题❗ */
public class CD102_1
{
    public static void main(String[] args)
    {
        int T, n, p, m;
        Scanner in = new Scanner(System.in);
        T = in.nextInt();
        while (T-- > 0)
        {
            n = in.nextInt();
            p = in.nextInt();
            m = in.nextInt();
            System.out.println(Math.max(0, 2 * n - 3));
        }
    }
}

CD105 可见的山峰对数量(进阶)❗

/* ❗单调栈❗ */
public class CD105_1
{
    public static int solution(int[] arr)
    {
        if (arr == null || arr.length < 2) return 0;
        int size = arr.length;
        int maxIndex = 0;
        for (int i = 0; i < size; i++)
            maxIndex = arr[maxIndex] < arr[i] ? i : maxIndex;
        Stack<int[]> stack = new Stack<>();
        stack.push(new int[]{arr[maxIndex], 1});
        int index = nextIndex(maxIndex, size);
        int res = 0;
        while (index != maxIndex)
        {
            while (stack.peek()[0] < arr[index])
            {
                int k = stack.pop()[1];
                res += getInternalSum(k) + 2 * k;
            }
            if (stack.peek()[0] == arr[index])
                stack.peek()[1]++;
            else
                stack.push(new int[]{arr[index], 1});
            index = nextIndex(index, size);
        }
        while (stack.size() > 2)
        {
            int times = stack.pop()[1];
            res += getInternalSum(times) + 2 * times;
        }
        if (stack.size() == 2)
        {
            int times = stack.pop()[1];
            res += getInternalSum(times) + (stack.peek()[1] == 1 ? times : 2 * times);
        }
        res += getInternalSum(stack.pop()[1]);
        return res;
    }

    public static int getInternalSum(int k)
    {
        return k == 1 ? 0 : (k * (k - 1) / 2);
    }

    public static int nextIndex(int i, int size)
    {
        return i < (size - 1) ? (i + 1) : 0;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();
        int[] m = new int[N];
        for (int i = 0; i < N; i++)
            m[i] = in.nextInt();
        System.out.println(solution(m));
    }
}

标签:arr,队列,incStack,左神,面试,int,isEmpty,new,public
From: https://www.cnblogs.com/VividBinGo/p/17815231.html

相关文章

  • 面试必刷TOP101:22、比较版本号
    题目题解publicintcompare(Stringversion1,Stringversion2){//用双指针遍历两个字符串//截取.之前的数字,//比较数字大小,返回1、-1;如果全部比较完都没有结果,返回0//关键在于处理前导0:加在前面数字乘10的后面010-->1000010-->10......
  • Java 并发多线程面试题及答案
    1、并发编程三要素?(1)原子性原子性指的是一个或者多个操作,要么全部执行并且在执行的过程中不被其他操作打断,要么就全部都不执行。(2)可见性可见性指多个线程操作一个共享变量时,其中一个线程对变量进行修改后,其他线程可以立即看到修改的结果。(3)有序性有序性,即程序的执行顺序......
  • 数据结构-队列和栈
    栈和队列是两种不同的数据形式,区别就是栈是先进后出,但是队列先进先出,可以用数据结构模拟这两种形式。1、队列完整代码如下:#include<stdio.h>#include<stdlib.h>#if0/*顺序队列*/intenQueue(int*a,intrear,intdata){a[rear]=data;rear++;retur......
  • 数据结构-队列
    一、概念1、队列的定义队列是仅限在一端进行插入,另一端进行删除的线性表。队列又被称为先进先出(FirstInFirstOut)的线性表,简称FIFO。2、队首允许进行元素删除的一端称为队首3、队尾允许进行元素插入的一端称为队尾二、接口1、可写接口(1)数据入队队列的插入操作,叫做入队。它是......
  • 单调队列学习笔记
    Menu单调队列(MonotonicQueue)简介代码模板例题单调栈(MonotonicStack)简介代码模板例题......
  • 每天5道Java面试题(第四天)
    1. Integer和int的区别?1、Integer是int的包装类,int则是java的一种基本数据类型 2、Integer变量必须实例化后才能使用,而int变量不需要 3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值。4、Integer的默认值是null,int的默认......
  • 面试题-高可用高并发问题
    原因:最近面试被问到高并发和高可用的问题,总是不知道怎么回答,于是做了这张图说明:从一条请求的发送这条思路走,就比较容易的回答出来了......
  • 队列(阻塞队列、非阻塞队列)的详解
    队列的详解什么是队列?用来存储一条条消息(线程)的容器是一个对列。队列是一种特殊的线性表,遵循先入先出、后入后出的基本原则什么是阻塞队列,什么是非阻塞队列?阻塞队列:添加元素时,超过总数则会进行等待(阻塞)。删除元素时,队列为空则会进行等待(阻塞)。非阻塞队列:不管什么情况下都......
  • 11月6日面试速成 | 面试是一个学习和成长的过程, 而不仅是一个简单的胜负局面
    通过面试的过程,你可以了解到这个岗位的具体要求和技术细节,从而能够更好地规划自己日后的学习计划。11.6号早上7点半醒来,忽然想到要视频面试很慌。在小红书上搜了一下要准备的问题,(好难。)1.“然后cnn的一些基础知识准备准备就行了,LSTM确保懂。还有什么过拟合呀、激活函数之类的......
  • Golang面试题从浅入深高频必刷「2023版」
    大家好,我是阳哥。专注Go语言的学习经验分享和就业辅导。Go语言特点Go语言相比C++/Java等语言是优雅且简洁的,是我最喜爱的编程语言之一,它既保留了C++的高性能,又可以像Java,Python优雅的调用三方库和管理项目,同时还有接口,自动垃圾回收和goroutine等让人拍案叫绝的设计。有许多基于......