代码随想录——栈与队列

news2024/11/24 20:30:20

232.用栈实现队列

力扣题目链接

使用栈实现队列的下列操作:

push(x) – 将一个元素放入队列的尾部。
pop() – 从队列首部移除元素。
peek() – 返回队列首部的元素。
empty() – 返回队列是否为空。

示例:

MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek();  // 返回 1
queue.pop();   // 返回 1
queue.empty(); // 返回 false

说明:

  • 你只能使用标准的栈操作 – 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。

思路

两个栈实现一个队列,一个栈顺序存放元素,一个栈逆序存放元素,两个栈同时只能一个栈存放元素,要么是顺序存放,要么是逆序存放。

代码实现

class MyQueue {

    Stack<Integer> stack1;
    Stack<Integer> stack2;

    public MyQueue() {
        //顺序存放元素
        stack1 = new Stack<>();

        //逆序存放元素
        stack2 = new Stack<>();
        //两个栈同时只能一个栈存放元素,要么顺序存放,要么逆序存放
    }

    public void push(int x) {
        while (!stack2.isEmpty()) {
            stack1.push(stack2.pop());
        }
        stack1.push(x);
    }

    public int pop() {
        while (!stack1.isEmpty()) {
            stack2.push(stack1.pop());
        }
        return stack2.pop();
    }

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

    public boolean empty() {
        return stack1.size() == 0 && stack2.size() == 0;
    }
}

225. 用队列实现栈

力扣题目链接

使用队列实现栈的下列操作:

实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false

注意:

  • 你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
  • 你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
  • 你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。

思路

栈和队列只是一种抽象概念,底层可以用任意数据结构实现。只需保证维护栈和队列基本特征,栈:先进后出;队列:先进先出。任何实现都是OK的。

下面就是使用一个队列来实现栈。【双端队列直接调API】

代码实现

class MyStack {
    //使用一个队列来实现栈
    LinkedList<Integer> queue;

    public MyStack() {
       queue = new LinkedList<>();
    }
    
    public void push(int x) {
        queue.addFirst(x);
    }
    
    public int pop() {
        return queue.removeFirst();
    }
    
    public int top() {
        return queue.getFirst();
    }
    
    public boolean empty() {
        return queue.isEmpty();
    }
}

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppopempty)。

只需要统一操作规则,实现起来就不算难,例如:我的pop()和top()操作,有着统一的规则:让queue1每次都存放的是栈顶元素

代码实现

public class MyStack2 {
    /**
     * 使用两个队列来实现栈
     */
    Queue<Integer> queue1;
    Queue<Integer> queue2;

    public MyStack2() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }

    public void push(int x) {
        queue1.offer(x);
    }

    public int pop() {
        //queue1只维护一个栈顶元素
        int size = queue1.size();

        //size >= 1
        while (size > 1){
            queue2.offer(queue1.poll());
            size--;
        }

        if (size == 1){
            return queue1.poll();
        }

        //size = 0
        while (!queue2.isEmpty()){
            queue1.offer(queue2.poll());
            size++;
        }

        while (size > 1){
            queue2.offer(queue1.poll());
            size--;
        }
        return queue1.poll();
    }

    public int top() {
        //queue1只维护一个栈顶元素
        int size = queue1.size();

        while (size > 1){
            queue2.offer(queue1.poll());
            size--;
        }

        if (size == 1){
            return queue1.peek();
        }

        while (!queue2.isEmpty()){
            queue1.offer(queue2.poll());
            size++;
        }

        while (size > 1){
            queue2.offer(queue1.poll());
            size--;
        }
        return queue1.peek();
    }

    public boolean empty() {
        return queue1.isEmpty() && queue2.isEmpty();
    }

Queue的一些API解释

api用法
peek()返回但不删除此队列的头部,如果此队列为空,则返回null。
element()返回但不删除此队列的头部。此方法与peek的区别仅在于如果此队列为空,它将抛出异常。(而不是返回null)
poll()返回并删除此队列的头部,如果此队列为空,则返回null。
remove()返回并删除此队列的头部。此方法与poll的不同之处仅在于如果此队列为空,则抛出异常
offer(E e)如果可以在不违反容量限制的情况下立即将指定元素插入此队列,则在成功时返回true,如果当前没有可用空间,不会抛异常,仅不会添加成功返回false。
add(E e)如果可以在不违反容量限制的情况下立即将指定元素插入此队列,则在成功时返回true,如果当前没有可用空间,则抛出IllegalStateException。

20. 有效的括号

力扣题目链接

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串,判断字符串是否有效。

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。
  • 注意空字符串可被认为是有效字符串。

示例 1:

  • 输入: “()”
  • 输出: true

示例 2:

  • 输入: “()[]{}”
  • 输出: true

示例 3:

  • 输入: “(]”
  • 输出: false

示例 4:

  • 输入: “([)]”
  • 输出: false

示例 5:

  • 输入: “{[]}”
  • 输出: true

思路

括号匹配是使用栈解决的经典问题。

看代码就能看懂,直接上代码

代码实现

 public boolean isValid(String s) {
        if (s.length() % 2 != 0) {
            return false;
        }
        // java8新特性–双括号初始化map
        Map<Character, Character> map = new HashMap<Character, Character>(3) {{
            put(')', '(');
            put(']', '[');
            put('}', '{');
        }};
     	//借助栈
        Stack<Character> stack = new Stack<>();
        for (char c : s.toCharArray()) {
            if (map.containsValue(c)) {
                stack.push(c);
            } else {
                //先出现反括号直接返回false
                if (stack.isEmpty()) {
                    return false;
                }

                //peek返回栈顶元素不删除,pop弹出并返回栈顶元素
                if (!stack.peek().equals(map.get(c))) {
                    //只要栈顶元素跟该元素不匹配直接返回false
                    return false;
                } else {
                    //弹出栈顶元素
                    stack.pop();
                }
            }
        }

        return stack.isEmpty();
    }

1047. 删除字符串中的所有相邻重复项

力扣题目链接

给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

示例:

  • 输入:“abbaca”
  • 输出:“ca”
  • 解释:例如,在 “abbaca” 中,我们可以删除 “bb” 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 “aaca”,其中又只有 “aa” 可以执行重复项删除操作,所以最后的字符串为 “ca”。

提示:

  • 1 <= S.length <= 20000
  • S 仅由小写英文字母组成。

思路

操作过程如下:
在这里插入图片描述

依旧是栈的经典应用,直接使用栈,最后栈不能直接转成字符串,还需要使用额外空间反转栈元素,费时费空间。

使用StringBuilder来充当栈,不需借助额外空间,到最后能直接返回结果。

代码实现

 public String removeDuplicates(String s) {
//        //直接使用栈
//        Stack<Character> stack = new Stack<>();
//        for (char c : s.toCharArray()) {
//            if (!stack.isEmpty() && stack.peek().equals(c)) {
//                stack.pop();
//            } else {
//                stack.push(c);
//            }
//        }
//
//        String ans = "";
//        //字符串反转
//        while (!stack.isEmpty()){
//            ans = stack.pop() + ans;
//        }
//        return ans;

        //StringBuilder 充当栈
        StringBuilder sb = new StringBuilder();
        for (char c : s.toCharArray()) {
            if (sb.length() > 0 && sb.charAt(sb.length() - 1) == c) {
                sb.deleteCharAt(sb.length() - 1);
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

150. 逆波兰表达式求值

力扣题目链接

根据 逆波兰表示法,求表达式的值。

有效的运算符包括 + , - , * , / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

示例 1:

  • 输入: [“2”, “1”, “+”, “3”, " * "]
  • 输出: 9
  • 解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

示例 2:

  • 输入: [“4”, “13”, “5”, “/”, “+”]
  • 输出: 6
  • 解释: 该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

示例 3:

  • 输入: [“10”, “6”, “9”, “3”, “+”, “-11”, " * ", “/”, " * ", “17”, “+”, “5”, “+”]

  • 输出: 22

  • 解释:该算式转化为常见的中缀算术表达式为:

    ((10 * (6 / ((9 + 3) * -11))) + 17) + 5       
    = ((10 * (6 / (12 * -11))) + 17) + 5       
    = ((10 * (6 / -132)) + 17) + 5     
    = ((10 * 0) + 17) + 5     
    = (0 + 17) + 5    
    = 17 + 5    
    = 22    
    

逆波兰表达式:是一种后缀表达式,所谓后缀就是指算符写在后面。

平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。

该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。

思路

逆波兰表达式主要有以下两个优点:

  • 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
  • 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。操作完成后,栈中只有一个元素,该元素就是最后结果

注意两数字操作前后顺序即可

操作过程如下:
在这里插入图片描述

代码实现

    public int evalRPN(String[] tokens) {
       Stack<Integer> stack = new Stack<>(); 
       //加法、乘法两个元素先后顺序无所谓,减法、除法两个元素顺序不能被改变
       for(String s : tokens){
           if("+".equals(s)){   
            stack.push(stack.pop() + stack.pop()); 
           }else if("-".equals(s)){
            stack.push(-stack.pop() + stack.pop()); 
           }else if("*".equals(s)){
            stack.push(stack.pop() * stack.pop()); 
           }else if("/".equals(s)){
            int first = stack.pop();
            stack.push(stack.pop() / first); 
           }else{
            stack.push(Integer.parseInt(s));
           }
       }      

        //到最后栈中只有一个元素,该元素就是最后的结果
        return stack.pop();
    }

347.前 K 个高频元素

力扣题目链接

给定一个非空的整数数组,返回其中出现频率前 k 高的元素。

示例 1:

  • 输入: nums = [1,1,1,2,2,3], k = 2
  • 输出: [1,2]

示例 2:

  • 输入: nums = [1], k = 1
  • 输出: [1]

提示:

  • 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
  • 你的算法的时间复杂度必须优于 O ( n log ⁡ n ) O(n \log n) O(nlogn) , n 是数组的大小。
  • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。
  • 你可以按任意顺序返回答案。

思路

这道题目主要涉及到如下三块内容:

  1. 要统计元素出现频率
  2. 对频率排序
  3. 找出前K个高频元素

首先统计元素出现的频率,这一类的问题可以使用map来进行统计。(key存元素,value存元素出现次数即可)

然后是对频率进行排序,这里我们可以使用一种 集合就是优先级队列

什么是优先级队列?

其实就是一个披着队列外衣的堆,因为优先级队列对外接口只是从队头取元素,从队尾添加元素,再无其他取元素的方式,看起来就是一个队列。

而且优先级队列内部元素是自动依照元素的权值排列。Java中PriorityQueue通过二叉小顶堆实现,可以用一棵完全二叉树表示。当然我们也可以自己指定排序规则。

得益于它的这个构造器public PriorityQueue(Comparator<? super E> comparator),因此我们可以通过实现Comparator接口自定义排序规则

什么是堆?

堆是一棵完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值。 如果父亲结点是大于等于左右孩子就是大顶堆,小于等于左右孩子就是小顶堆。

对于该题我们可以使用大顶堆也可以使用小顶堆。

大顶堆:

优先级队列中不限制元素数量,将上述统计得到的map中的所有元素放入优先级队列,最后取出优先级队列前k个元素即可。这种做法的时间复杂度是O(n log n),不是最优解,而且我们只需要k个元素,没必要对所有元素进行排序,最后取出前k个。

小顶堆:

使用小顶堆的话,我们可以只在优先级队列中存k个元素,当第k + 1个元素过来时与堆顶元素出现次数比较(堆顶元素出现次数最小),如果该元素出现次数大于堆顶元素,只需移除堆顶元素放入该元素即可,最后队列中元素就是我们需要的k个元素。该种做法的时间复杂度是O(n log k)。当元素个数n很大,需要找到元素个数k很小时,这种做法效率明显比大顶堆高很多。

代码实现

   /*Comparator接口说明:
    * 默认从小到大升序【队头到队尾】小顶堆
    * 
	* 返回负数,形参中第一个参数排在前面;返回正数,形参中第二个参数排在前面
	* 对于队列:排在前面意味着往队头靠
	* 
 	* 对于堆(使用PriorityQueue实现):从队头到队尾按从小到大排就是最小堆(小顶堆),
 	*                               从队头到队尾按从大到小排就是最大堆(大顶堆)--->队头元素相当于堆的根节点
 	* (pair1, pair2) -> pair1.getValue() - pair2.getValue() 根据元素出现频率升序,对于堆而言就是小顶堆	
	* */ 
	public int[] topKFrequent(int[] nums, int k) {
        int[] ans = new int[k];
        Map<Integer, Integer> map = new HashMap<>();
        //使用map统计元素出现次数
        for (int num : nums) {
            map.put(num, map.getOrDefault(num, 0) + 1);
        }

        //优先级队列,出现次数按从队头到队尾的顺序是从小到大排,出现次数最低的在队头(相当于小顶堆)
        PriorityQueue<Map.Entry<Integer, Integer>> priorityQueue = new PriorityQueue<>((pair1, pair2) -> pair1.getValue() - pair2.getValue());
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            if (priorityQueue.size() < k) {
                priorityQueue.add(entry);
            } else {
                //队列中只维护k个元素,当当前元素出现个数大于堆顶元素出现个数(小顶堆)时,移除队头元素放入当前元素
                if (entry.getValue() > priorityQueue.peek().getValue()) {
                    priorityQueue.poll();
                    priorityQueue.add(entry);
                }
            }
        }

        int index = k - 1;
        while (!priorityQueue.isEmpty()) {
            ans[index--] = priorityQueue.poll().getKey();
        }
        

        //基于大顶堆实现,从头到尾出现频率依次递减
//        PriorityQueue<Map.Entry<Integer, Integer>> priorityQueue = new PriorityQueue<>((pair1, pair2) -> pair2.getValue() - pair1.getValue());
//        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
//            priorityQueue.add(entry);
//        }
//
//        //直接取前k个元素即可
//        for (int i = 0; i < k; i++) {
//            ans[i] = priorityQueue.poll().getKey();
//        }
        return ans;
    }

239. 滑动窗口最大值

力扣题目链接

给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。

进阶:

你能在线性时间复杂度内解决此题吗?

image-20221201230406759

提示:

  • 1 <= nums.length <= 10^5
  • -10^4 <= nums[i] <= 10^4
  • 1 <= k <= nums.length

思路

这题完全可以用优先级队列来解题,优先级队列中只维护k个元素,可以使用大顶堆,窗口每次移动,堆顶也就是队列头就是我们要的元素,放到结果中,这种解法理论上可行。(但是会超时~)

代码如下:

  public int[] maxSlidingWindow(int[] nums, int k) {
        if (nums.length == 1) {
            return nums;
        }
        int len = nums.length - k + 1;
        int[] ans = new int[len];
        //一、大顶堆
        PriorityQueue<Integer> queue = new PriorityQueue<>((num1, num2) -> num2 -num1);
        for(int i = 0; i < len; i++){
            //每次进来清空队列,让队列中只维护k个元素
            queue.clear();
            int temp = i;
            while(temp < i + k){
                queue.add(nums[temp++]);
                ans[i] = queue.peek();
            }
        }
        return ans;
    }

实际上我们需要一个队列,这个队列呢,放进去窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动之后,队列告诉我们里面的最大值是什么。

这个队列应该长这个样子:

class MyQueue {
        void pop(int val) {}

        void push(Integer val) {}

        public int getMax() {}

    }

每次窗口移动的时候,调用que.pop(滑动窗口中移除元素的数值),que.push(滑动窗口添加元素的数值),然后que.getMax()就返回我们要的最大值。

实际上Java中没有这样的数据结构,我们需要自己实现这么个队列。


然后再分析一下,队列里的元素一定是要排序的,而且要最大值放在出队口,要不然怎么知道最大值呢。

但如果把窗口里的元素都放进队列里,窗口移动的时候,队列需要弹出元素。

那么问题来了,已经排序之后的队列 怎么能把窗口要移除的元素(这个元素可不一定是最大值)弹出呢。

主要思想是队列没有必要维护窗口里的所有元素,只需要维护有可能成为窗口里最大值的元素就可以了,同时保证队列里的元素数值是由大到小的。


那么这个维护元素单调递减的队列就叫做单调队列,即单调递减或单调递增的队列。

而且不要以为实现的单调队列就是 对窗口里面的数进行排序,如果仅仅排序的话,那和优先级队列又有什么区别了呢。

设计单调队列的时候,pop,和push操作要保持如下规则:

  1. pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作
  2. push(value):如果push的元素value大于入口元素的数值,那么就将队列出口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止

保持如上规则,每次窗口移动的时候,只要问que.getMax()【直接返回队头元素】就可以返回当前窗口的最大值。
动画过程:
在这里插入图片描述

首先要明确的是,题解中单调队列里的pop和push接口,仅适用于本题。

单调队列不是一成不变的,而是不同场景不同写法,总之要保证队列里单调递减或递增的原则,所以叫做单调队列。

不要以为本题中的单调队列实现就是固定的写法。

代码实现

(自定义单调队列以及直接使用双端队列来实现单调队列)

public int[] maxSlidingWindow(int[] nums, int k) {
        if (nums.length == 1) {
            return nums;
        }
        int len = nums.length - k + 1;
        int[] ans = new int[len];
        //二、自定义单调栈:单调队列只维护可能是最大值的数
//        MyQueue queue = new MyQueue();
//        int index = 0;
//        //先push前k个元素
//        for (int i = 0; i < k; i++) {
//            queue.push(nums[i]);
//        }
//        ans[index++] = queue.getMax();
//
//        for (int i = k; i < nums.length; i++) {
//            //弹出最开始的元素
//            queue.pop(nums[i - k]);
//            queue.push(nums[i]);
//            ans[index++] = queue.getMax();
//        }

        //直接使用双端队列实现单调栈
        Deque<Integer> deque = new LinkedList<>();
        int index = 0;
        for (int i = 0; i < nums.length; i++) {
            //先pop 弹出开始元素
            if (!deque.isEmpty() && i - k >= 0 && nums[i - k] == deque.peekFirst()) {
                deque.removeFirst();
            }

            //再push
            while (!deque.isEmpty() && deque.getLast() < nums[i]) {
                deque.removeLast();
            }
            deque.add(nums[i]);
            //最后取出最大元素[队头元素],从前k个元素开始
            if (i >= k - 1) {
                ans[index++] = deque.peekFirst();
            }
        }
        return ans;
    }


    /**
     * 自定义单调队列
     * 队列中元素从头到尾依次递减,
     * pop元素时,开始元素与队头元素相等时,pop出队头元素
     * push元素时,队尾元素比当前元素小将该元素弹出(因此需要双端队列)直到队尾元素大于等于当前元素,再把当前元素添加到队尾
     * 每次pop、push结束之后,获取队列中最大值(即队头元素)getMax
     */
    static class MyQueue {
        Deque<Integer> deque = new LinkedList<>();

        void pop(int val) {
            //只有开始值与队头元素相等,才将队头元素弹出
            if (!deque.isEmpty() && deque.getFirst() == val) {
                deque.removeFirst();
            }
        }

        void push(Integer val) {
            //只要队尾值比当前元素小,直接从队尾弹出
            while (!deque.isEmpty() && deque.getLast() < val) {
                deque.removeLast();
            }

            deque.addLast(val);
        }

        //返回队头最大值
        public int getMax() {
            return deque.peek();
        }

    }

详情见代码随想录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/53322.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何使用qemu调试内核

文件系统 调试内核需要一个基本的文件系统&#xff0c;我们可以使用简单的 ramdisk来作为这个文件系统&#xff0c;如果&#xff0c;需要测试一些其它应用程序&#xff0c;我们还需要创建一个大一点根文件系统。 Ramdisk 也就是内核启动时的initrd.img&#xff0c;可以使用b…

iOS创建苹果证书、制作p12证书流程

一、创建Certificates 1、在苹果开发者后台点击右上角【Account】进入以下界面&#xff0c;然后点击【Certificates, Identifiers & Profiles】 2、进入以下界面后点击【Create a certificate】 3、然后选择证书类型&#xff0c;Apple Development&#xff08;开发者证书…

Oracle中ALTER TABLE的五种用法(四、五)

首发微信公众号&#xff1a;SQL数据库运维 原文链接&#xff1a;https://mp.weixin.qq.com/s?__bizMzI1NTQyNzg3MQ&mid2247485212&idx1&sn450e9e94fa709b5eeff0de371c62072b&chksmea37536cdd40da7a94e165ce4b4c6e70fb1360d51bed4b3566eee438b587fa231315d0a5a…

MySQL数据库复习——事务

目录 一、什么是事务&#xff1f;为什么需要事务 二、事务的四大特性&#xff08;ACID&#xff09; 三、事务的使用 四、并发带来的问题 1、脏读问题 2、不可重复读 3、幻读 五、MySQL的隔离级别 一、什么是事务&#xff1f;为什么需要事务 事务的概念&#xff1a; 事务…

深度解析Linux内核—中断

中断 中断是外围设备通知处理器的一种机制。 1. 中断控制器 外围设备不是把中断请求直接发送给处理器&#xff0c;而是发给中断控制器&#xff0c;由中断控制器转发给处理器。 不同种类的中断控制器的访问方法存在差异&#xff0c;为了屏蔽差异&#xff0c;内核定义了中断控…

model.eval 至关重要!!!!model.eval()是否开启 BN 和 Dropout 的不同

之前写过一个项目&#xff0c;eval的时候很正常&#xff0c;但是一infer就有问题&#xff0c;多次排查发现&#xff0c;原来就是只缺一个 model.eval()哇&#xff0c;重大教训&#xff0c;我debug好久&#xff0c;在小姑娘面前翻车… &#x1f923;&#x1f923;&#x1f923;…

样本与抽样分布(2)-基本分布

本节介绍在数理统计中常用的几个基本分布。为此&#xff0c;先引进分位数定义。 定义1. 2. 1 设X为随机变量&#xff0c;则称满足 的为X的上侧分位数,简称为(上侧)分位数. 1 标准正态分布 标准正态分布N (0,1)是构造其他分布的基础&#xff0c;其密度函数为 它的图形关于y轴…

【毕业设计】深度学习卫星遥感图像检测与识别系统(目标检测)

文章目录0 前言1 课题背景2 实现效果3 Yolov5算法4 数据处理和训练5 最后0 前言 &#x1f525; Hi&#xff0c;大家好&#xff0c;这里是丹成学长的毕设系列文章&#xff01; &#x1f525; 对毕设有任何疑问都可以问学长哦! 这两年开始&#xff0c;各个学校对毕设的要求越来…

LeetCode-44-通配符匹配

1、递归 具体思路同LeetCode-剑指19-正则表达式匹配&#xff0c;但在本题中由于字符串长度过长会导致超时。 在这里插入代码片class Solution { public:bool isMatch(string s, string p) {if (p.empty()) return s.empty();bool first_match !s.empty() && (s[0] …

Gradle修改镜像库 ,初始启动配置 init.gradle

目录 ■前言 ■代码放置位置 ■具体代码 代码建议&#xff1a; ■Gradle 的 更多知识&#xff08;私密&#xff09; ■前言 默认镜像库太慢了&#xff0c;在【初始启动配置&#xff08;init.d&#xff09;】中&#xff0c;添加xxx.gradle (init.gradle) 文件&#xff0c;指…

网络自动化运维(NetDevOps)创作者推荐

前言&#xff1a; 随着NetDevOps技术登上了历史舞台&#xff0c;越来越多的从业者开始利用NetDevOps简化网络的运维&#xff0c;并进行了技术分享&#xff0c;将蛋糕越做越大。在这里&#xff0c;仅代表个人对这些无私奉献的网络、运维工程师们表达由衷的敬意。 此外&#xff…

用户身份验证的令牌—Token教程

一、什么是Token&#xff1f; 1、Token的引入&#xff1a;Token是在客户端频繁向服务端请求数据&#xff0c;服务端频繁的去数据库查询用户名和密码并进行对比&#xff0c;判断用户名和密码正确与否&#xff0c;并作出相应提示&#xff0c;在这样的背景下&#xff0c;Token便应…

学习二十大奋进新征程线上知识答题小程序登录技术点分析与实现

学习二十大奋进新征程线上知识答题小程序登录技术点分析与实现 在最新搭建的知识答题小程序&#xff0c;遇到了微信授权登录上的技术难点&#xff0c;所以对于以往的那套登录框架不能使用了&#xff0c;需要搭建一套新的注册登录流程框架。 不得不做出调整&#xff0c;为此&a…

json交叉编译并移植到嵌入式开发板

1、解压&#xff1a;tar -xvf json-c-0.9.tar.gz 默认解压在当前目录 2、进入解压后的目录&#xff1a;$ cd cd json-c-0.9/ 3、执行&#xff1a; sudo ./configure CCaarch64-linux-gnu-gcc --hostarm-linux --prefix/opt/json-c-0.9/ 说明&#xff1a;CC赋值为嵌入式开发环…

Java之线程详解(二)——线程安全概述、synchronized锁

一、线程安全概述 什么是线程安全问题&#xff1f; 当多个线程共享同一个全局变量&#xff0c;做写的操作时&#xff08;即修改该全局变量&#xff09;&#xff0c;可能会受到其他的线程干扰&#xff0c;发生线程安全问题。 eg&#xff1a; public class Thread01 implemen…

丝裂原活化蛋白激酶TaMPK3抑制植物对ABA的反应

文章信息 题目&#xff1a;Mitogen-activated protein kinase TaMPK3 suppresses ABA response by destabilising TaPYL4 receptor in wheat 刊名&#xff1a;New Phytologist 作者&#xff1a;Ying Liu&#xff0c;You-Zhi Ma, Zhao-Shi Xu et al. 单位&#xff1a;Instit…

【Linux】如何在Linux下提交代码到gittee

文章目录使用 git 命令行创建项目三板斧第一招: git add三板斧第二招: git commit三板斧第三招: git push其他几个重要的命令git pull&#xff08;将远端同步到本地&#xff09;git rm&#xff08;删除&#xff09;git log&#xff08;查看提交日志&#xff09;使用 git 命令行…

GPT语言模型

GPT&#xff1a;GPT采用了大量的无监督的数据进行预训练&#xff08;Pre-training&#xff09;&#xff0c;并在有监督的数据上进行微调&#xff08;Fine-tuning&#xff09;来做具体的NLP的任务。结构&#xff1a;GPT使用了12层12头&#xff0c;单向transformer的decoder部分&…

2001-2020年全国31省城镇居民人均可支配收入/居民实际收入水平

1、时间区间为&#xff1a;2001-2020年 2、范围包括&#xff1a;全国31省 3、基期&#xff1a;以2001年为基期 4、来源&#xff1a;国家统计J 5、指标包括&#xff1a; 城市居民消费价格指数(上年100)、城镇居民人均可支配收入(元)、实际可支配收入&#xff08;2001年为基…

LabVIEW开发LabVIEW类

LabVIEW开发LabVIEW类 从概念上来说&#xff0c;LabVIEW面向对象编程和其它面向对象编程语言相似。但由于LabVIEW是数据流图形化编程环境&#xff0c;LabVIEW对类数据的操作和交互&#xff0c;以及LabVIEW类代码的调试方法和其它语言有所不同。 LabVIEW中的对象由值来传递&a…