【代码随想录】+ leetcode hot100:栈与队列算法专题总结、单调栈

大家好,我是此林。

今天分享的是【代码随想录】栈与队列算法专题总结,分享刷算法的心得体会。

1. 用栈实现队列、用队列实现栈

232. 用栈实现队列 - 力扣(LeetCode)

225. 用队列实现栈 - 力扣(LeetCode)

这两题放在一起,比较相似。

1. 用栈实现队列:使用两个栈,根本是让出栈顺序和队列一样

stack1 = new Stack<>(); // 主栈,和队列顺序一致
stack2 = new Stack<>(); // 辅助栈

2. 用队列实现栈:使用两个队列,根本是让出队顺序一样

queue1 = new LinkedList<>(); // 主队列,和栈顺序一致
queue2 = new LinkedList<>(); // 辅助队列

所以无论是队列还是栈,只要重点改push的逻辑即可。

class MyQueue {Stack<Integer> stack1;Stack<Integer> stack2;public MyQueue() {stack1 = new Stack<>();stack2 = new Stack<>();}public void push(int x) {// 重点改这里的逻辑}public int pop() {return stack1.pop();}public int peek() {return stack1.peek();}public boolean empty() {return stack1.isEmpty();}
}
class MyStack {Queue<Integer> queue1;Queue<Integer> queue2;public MyStack() {queue1 = new LinkedList<>();queue2 = new LinkedList<>();}public void push(int x) {// 重点改这里的逻辑}public int pop() {return queue1.poll();}public int top() {return queue1.peek();}public boolean empty() {return queue1.isEmpty();}
}

其他方法,因为 stack1 或者 queue1 和 队列 或者 栈 的顺序一致,所以只需要操作对应方法即可。

用栈实现队列完整代码

class MyQueue {Stack<Integer> stack1;Stack<Integer> stack2;public MyQueue() {stack1 = new Stack<>();stack2 = new Stack<>();}public void push(int x) {while (!stack1.isEmpty()) {stack2.push(stack1.pop());}stack2.push(x);while (!stack2.isEmpty()) {stack1.push(stack2.pop());}}public int pop() {return stack1.pop();}public int peek() {return stack1.peek();}public boolean empty() {return stack1.isEmpty();}
}

用队列实现栈完整代码:

class MyStack {Queue<Integer> queue1;Queue<Integer> queue2;public MyStack() {queue1 = new LinkedList<>();queue2 = new LinkedList<>();}public void push(int x) {queue2.offer(x);while (!queue1.isEmpty()) {queue2.offer(queue1.poll());}Queue<Integer> tmp = queue1;queue1 = queue2;queue2 = tmp;}public int pop() {return queue1.poll();}public int top() {return queue1.peek();}public boolean empty() {return queue1.isEmpty();}
}

2. 有效的括号

20. 有效的括号 - 力扣(LeetCode)

这题本质思路:实现一个栈,

1. 如果是左括号直接入栈,

2. 如果是右括号则和第一个出栈的左括号比对,如果匹配,左括号出栈。

如此循环,最后看栈是否Empty,如果不为空,则非有效括号(false)。

那么左右括号比对,可以写一个HashMap做映射。

class Solution {public boolean isValid(String s) {Map<Character, Character> map = new HashMap<>();map.put(']', '[');map.put(')', '(');map.put('}', '{');Stack<Character> stack = new Stack<>();for (char c : s.toCharArray()) {// 如果 c 是左括号,直接入栈if (c == '(' || c == '[' || c == '{') {stack.push(c);} else {if (!stack.isEmpty() && stack.peek() == map.get(c)) {stack.pop();} else {stack.push(c);}}}return stack.isEmpty();}
}

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

1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)

这题和 有效括号 的思路是一样的,甚至更加简单。 

有效括号 还需要定义HashMap来做左右括号的匹配映射,本题只需要判断是否相等即可。

完整代码:

class Solution {public String removeDuplicates(String s) {Stack<Character> stack = new Stack<>();for (char c : s.toCharArray()) {if (!stack.isEmpty() && stack.peek() == c) {stack.pop();} else {stack.push(c);}}String res = "";while (!stack.isEmpty()) {res = stack.pop() + res;}return res;}
}

需要注意的是,最后出栈顺序会颠倒,所以不能直接 res += stack.pop(),

要改成 res = stack.pop() + res。

4. 逆波兰表达式求值

150. 逆波兰表达式求值 - 力扣(LeetCode)

这题其实也不难,

整体思路是遍历 tokens,如果是数字,直接入栈;

如果是运算符(+、-、*、/),那么就 stack.pop() 出栈两次,然后把取得两个数字做对应的运算,得到的结果入栈即可。

完整代码:

class Solution {public int evalRPN(String[] tokens) {Stack<Integer> stack = new Stack<>();for (String s : tokens) {switch (s) {case "+":stack.push(Integer.valueOf(stack.pop()) + Integer.valueOf(stack.pop()));break;case "-":int a = Integer.valueOf(stack.pop());int b = Integer.valueOf(stack.pop());stack.push(b - a);break;case "*":stack.push(Integer.valueOf(stack.pop()) * Integer.valueOf(stack.pop()));break;case "/":a = Integer.valueOf(stack.pop());b = Integer.valueOf(stack.pop());stack.push(b / a);break;default:// 数字直接入栈stack.push(Integer.valueOf(s));}}return stack.pop();}
}

可以看到,一个 switch 解决一切。

需要注意的是,减法和出除法需要颠倒下位置。

虽然这样写思路可能比较清晰,但是代码有点冗余,特别是 Integer.valueOf() 被频繁使用。

改写优化:

class Solution {public int evalRPN(String[] tokens) {Set<String> set = new HashSet<>();set.add("+");set.add("-");set.add("*");set.add("/");Stack<Integer> stack = new Stack<>();for (String token : tokens) {// 如果 token 为数字if (!set.contains(token)) {stack.push(Integer.valueOf(token));} else {Integer a = stack.pop();Integer b = stack.pop();if (token.equals("+")) {stack.push(a + b);} else if (token.equals("-")) {stack.push(b - a);} else if (token.equals("*")) {stack.push(a * b);} else if (token.equals("/")) {stack.push(b / a);}}}return stack.pop();}
}

5. 前 K 个高频元素

347. 前 K 个高频元素 - 力扣(LeetCode)

这题没什么花头,常规思路而已:

1. 遍历nums,然后用HashMap统计每个num的出现次数

2. 根据出现次数对HashMap进行排序

重点在这个排序,因为题目说时间复杂度 必须 优于 O(n log n) 

所以排序用Java里现成的优先队列 PriorityQueue 即可,设置为大顶堆即可。

完整代码:

class Solution {public int[] topKFrequent(int[] nums, int k) {// 统计每个num出现的次数Map<Integer, Integer> map = new HashMap<>();for (int num : nums) {map.put(num, map.getOrDefault(num, 0) + 1);}// 对map进行从大到小排序PriorityQueue<int[]> queue = new PriorityQueue<>((o1, o2) -> o2[1] - o1[1]);for (Map.Entry<Integer, Integer> entry : map.entrySet()) {int[] tmp = new int[2];tmp[0] = entry.getKey();tmp[1] = entry.getValue();queue.offer(tmp);}// 封装TopK结果int[] res = new int[k];for (int i = 0; i < k; i++) {res[i] = queue.poll()[0];}return res;}
}

这里第一部分统计出现的次数没什么好说,

第二部分,PriorityQueue 是 Java 封装好的排序队列,每次加入队列的元素会自动排序,排序规则在构造方法里传入了:(o1, o2) -> o2[1] - o1[1]

这个tmp数组,tmp[0] 代表num,tmp[1] 代表num出现的次数

(o1, o2) -> o2[1] - o1[1] 其实就表示按照num出现的次数从大到小逆序排序。

6. 最小栈

155. 最小栈 - 力扣(LeetCode)

看到题目,第一反应就是新建一个 Stack<Integer> 和 一个 Integer min 变量。

于是,你写了下面的代码:

class MinStack {Stack<Integer> stack;int min = Integer.MAX_VALUE;public MinStack() {stack = new Stack<>();}public void push(int val) {if (val < min) {min = val;}stack.push(val);}public void pop() {stack.pop();}public int top() {return stack.peek();}public int getMin() {return min;}
}

这就有个问题,看下面例子:

入栈 3 
|   |   min = 3
|   |     
|_3_|    
stack   入栈 5 
|   |   min = 3
| 5 |     
|_3_|    
stack  入栈 2 
| 2 |   min = 2
| 5 |     
|_3_|    
stack  出栈 2 
|   |   min = 2?
| 5 |     
|_3_|    
stack  

如果只用一个变量就会遇到一个问题,如果把 min 更新为 2,那么之前的最小值 3 就丢失了。

怎么把 3 保存起来呢?把它在 2 之前压入栈中即可。

入栈 2 ,同时将之前的 min 值 3 入栈,再把 2 入栈,同时更新 min = 2
| 2 |   min = 2
| 3 |  
| 5 |     
|_3_|    
stack  入栈 6 
| 6 |  min = 2
| 2 |   
| 3 |  
| 5 |     
|_3_|    
stack  出栈 6     
| 2 |   min = 2
| 3 |  
| 5 |     
|_3_|    
stack  出栈 2 ,然后再出栈一次,把 3 赋值给 min 即可。    
|   |   min = 3
|   |  
| 5 |     
|_3_|    
stack  

完整代码:

class MinStack {Stack<Integer> stack;int min = Integer.MAX_VALUE;public MinStack() {stack = new Stack<>();}public void push(int val) {// 如果min需要变更了,先把旧的min入栈保存,再入栈新的min,同时更新minif (val <= min) {stack.push(min);min = val;}stack.push(val);}public void pop() {// 如果发现出栈的元素等于min,那么再出栈一次,并把min重新赋值if (stack.pop() == min) {min = stack.pop();}}public int top() {return stack.peek();}public int getMin() {return min;}
}

所以,这里的核心,就是把旧的min压栈做副本保存,再入栈新的min,同时更新min。

后续 pop() 出栈,如果发现出栈的元素等于min,就出栈两次即可。

当然,还有一种官方的解法,他另外用了一个辅助栈,其实思路大差不差,都是为了缓存旧的min。这里可以看下他的思路。

class MinStack {Stack<Integer> stack;Stack<Integer> stack1; // 辅助栈public MinStack() {stack = new Stack<>();stack1 = new Stack<>();stack1.push(Integer.MAX_VALUE);}public void push(int val) {stack.push(val);stack1.push(Math.min(val, stack1.peek()));}public void pop() {stack.pop();stack1.pop();}public int top() {return stack.peek();}public int getMin() {return stack1.peek();}
}

理解算法,重点在于带入例子,去理解他的过程,没有捷径可以走。

7. 字符串解码

394. 字符串解码 - 力扣(LeetCode)

这种题目就是纯模拟题,没有什么技巧可言。

总体思路:

1. 遍历字符串,如果不是 ],即数字或 [,直接入栈。

2. 如果是 ]

3. stack.pop() + while循环 提取出需要重复的字符串 tmp

4. stack.pop() + while循环 提取出需要重复的次数 time

5. 根据 time 和 tmp 重复字符串入栈,最后整合结果。

完整代码:

class Solution {public String decodeString(String s) {Stack<Character> stack = new Stack<>(); // 遍历字符串for (char c : s.toCharArray()) {// 如果不是 ] ,是数字或 [ ,直接入栈if (c != ']') {stack.push(i);} else {// 提取出需要遍历的字符串 tmpString tmp = "";while (stack.peek() != '[') {tmp = stack.pop() + tmp;}// 删掉 [stack.pop();// 提取出需要重复的次数 timeString time = "";while (!stack.isEmpty() && stack.peek() >= '0' && stack.peek() <= '9') {time = stack.pop() + time;}// 根据 tmp 和 time 重复出字符串入栈for (int i = 0; i < Integer.valueOf(time); i++) {for (char t : tmp.toCharArray()) {stack.push(t);}}}}// 整合结果为字符串String res = "";while (!stack.isEmpty()) {res = stack.pop() + res;}return res;}
}

8. 每日温度

从 每日温度 开始,往后题目均为 单调栈 的解题思路。

单调栈 模板:

Stack<Integer> stack = new Stack<>();for (int i = 0; i < arr.length; i++) {while (!stack.isEmpty() && arr[i] > arr[stack.peek()]) {// ...}stack.push(i);}

739. 每日温度 - 力扣(LeetCode)

 这题其实暴力法可以做,

第一个for循环遍历 temperatures,第二个for循环负责去找第一个比当前元素大的位置。

但是,本题用 单调栈 即可。

先明确两个事情:

1. 这个栈里存的元素是 数组下标,而不是实际元素。因为后续要计算间隔天数。

2. 这个栈是单调的,不过不是数组下标单调,而是数组下标对应的 temperature 每次入栈都应该比栈顶的要大。

为了方便理解,我们来理解过程。

首先,明确下面三个变量。

temperatures =  [73,74,75,71,69,72,76,73]  // 题目给出的温度列表Stack<Integer> stack = new Stack<>()  // 单调栈int[] res =  [0,0,0,0,0,0,0,0]  // 最终答案

1. 当 i=0 时,单调栈为空,因此将 0 进栈。

stack=[0(73)]

ans=[0,0,0,0,0,0,0,0]

2. 当 i=1 时,由于 74 大于 73,因此移除栈顶元素 0,赋值 ans[0]:=1−0,将 1 进栈。

stack=[1(74)]

ans=[1,0,0,0,0,0,0,0]

注:ans[0]:=1−0 表示计算天数间隔。

3. 当 i=2 时,由于 75 大于 74,因此移除栈顶元素 1,赋值 ans[1]:=2−1,将 2 进栈。

stack=[2(75)]

ans=[1,1,0,0,0,0,0,0]

4. 当 i=3 时,由于 71 小于 75,因此将 3 进栈。

stack=[2(75),3(71)]

ans=[1,1,0,0,0,0,0,0]

5. 当 i=4 时,由于 69 小于 71,因此将 4 进栈。

stack=[2(75),3(71),4(69)]

ans=[1,1,0,0,0,0,0,0]

6. 当 i=5 时,由于 72 大于 69 和 71,因此依次移除栈顶元素 4 和 3,赋值 ans[4]:=5−4 和 ans[3]:=5−3,将 5 进栈。

stack=[2(75),5(72)]

ans=[1,1,0,2,1,0,0,0]

7. 当 i=6 时,由于 76 大于 72 和 75,因此依次移除栈顶元素 5 和 2,赋值 ans[5]:=6−5 和 ans[2]:=6−2,将 6 进栈。

stack=[6(76)]

ans=[1,1,4,2,1,1,0,0]

8. 当 i=7 时,由于 73 小于 76,因此将 7 进栈。

stack=[6(76),7(73)]

ans=[1,1,4,2,1,1,0,0]

完整代码:

class Solution {public int[] dailyTemperatures(int[] temperatures) {Stack<Integer> stack = new Stack<>();int[] res = new int[temperatures.length];for (int i = 0; i < temperatures.length; i++) {while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) {int idx = stack.pop();res[idx] = i - idx;}stack.push(i);}return res;}
}

9. 柱状图中的最大的矩形

84. 柱状图中最大的矩形 - 力扣(LeetCode)

这题也是单调栈的思路。这里进入单调栈的还是数组索引下标,和 每日温度 一样

先说下算法的硬流程。

1. 输入 heights = [2, 1, 5, 6, 2, 3]

2. 加入哨兵(其实就是首尾两个0,方便后续代码):

    heights = [0, 2, 1, 5, 6, 2, 3, 0]

3. 进入遍历 heights 逻辑

完整代码:

class Solution {public int largestRectangleArea(int[] heights) {// 加入哨兵的逻辑int[] newHeights = new int[heights.length + 2];newHeights[0] = newHeights[newHeights.length - 1] = 0;for (int i = 0; i < heights.length; i++) {newHeights[i + 1] = heights[i];}int res = 0;Stack<Integer> stack = new Stack<>();// 遍历 heights 逻辑for (int i = 0; i < newHeights.length; i++) {while (!stack.isEmpty() && newHeights[i] < newHeights[stack.peek()]) {int idx = stack.pop();int w = i - stack.peek() - 1; // right - left - 1int h = newHeights[idx];res = Math.max(w * h, res);}stack.push(i);}return res;}
}

遍历 heights,是要以当前高度为基准,寻找最大的宽度 组成最大的矩形面积那就是要找左边第一个小于当前高度的下标left,再找右边第一个小于当前高度的下标right,那宽度就是这两个下标之间的距离了,但是要排除这两个下标,所以是  right - left - 1,用单调栈就可以很方便确定这两个边界了。

10. 下一个更大元素 I

496. 下一个更大元素 I - 力扣(LeetCode)

这题本来想用暴力做法先熟悉下题目的,结果暴力做法直接通过了......

完整代码也贴一下,这里就不多说了。

class Solution {public int[] nextGreaterElement(int[] nums1, int[] nums2) {int[] res = new int[nums1.length];for (int k = 0; k < nums1.length; k++) {OUT:for (int i = 0; i < nums2.length; i++) {if (nums1[k] == nums2[i]) {for (int j = i; j < nums2.length; j++) {if (nums2[j] > nums1[k]) {res[k] = nums2[j];break OUT;}}res[k] = -1;}}}return res;}
}

这题依旧可以用单调栈法。

完整代码:

class Solution {public int[] nextGreaterElement(int[] nums1, int[] nums2) {// 构建HashMap,映射为 nums[i] -> iMap<Integer, Integer> map = new HashMap<>();for (int i = 0; i < nums1.length; i++) {map.put(nums1[i], i);}Deque<Integer> stack = new LinkedList<>();int[] res = new int[nums1.length];Arrays.fill(res, -1); // -1 表示不存在// 遍历 nums2for (int x : nums2) {while (!stack.isEmpty() && x > stack.peek()) {// x 是栈顶的下一个更大元素// 既然栈顶已经算出答案,弹出res[map.get(stack.pop())] = x; // 记录结果到res}// 只有 nums1 存在的元素才入栈if (map.containsKey(x)) {stack.push(x);}}return res;}
}

举个例子过程:

nums1 = [4,1,2],  nums2 = [1,3,4,2],  stack = new Stack<>(),   res = [-1, -1, -1]

1. 遍历 nums2

2. 第一个元素 1 在nums1里,此时 stack 为 empty,直接加入 stack。

    stack:栈底 → [1]

3. 第二个元素 3 不在nums1里,元素 3 大于 stack.peek(),记录结果 3 到 res 数组。

    同时 stack.pop(),

    stack:栈底,res = [-1, 3, -1]

4. 第三个元素 4 在nums1里,此时 stack 为 empty,直接加入 stack。

    stack:栈底 → [4]

5. 第四个元素 2 在nums1里,元素 2 小于 stack.peek(),不记录结果。

    stack:栈底 → [4] → [2]

11. 下一个更大元素 II

503. 下一个更大元素 II - 力扣(LeetCode)

和  下一个更大元素 I 不同的是,这里的 nums 变成了 循环数组,也就是下一个更大的元素可能不在后面,但可能在前面!

这里用两次遍历即可解决,在 下一个更大元素 I 的基础上改下即可

完整代码:

class Solution {public int[] nextGreaterElements(int[] nums) {int n = nums.length;// 本题入栈的是数组下标Deque<Integer> stack = new LinkedList<>();int[] res = new int[n];Arrays.fill(res, -1);// 这里改为 n*2for (int i = 0; i < 2 * n; i++) {int x = nums[i % n];while (!stack.isEmpty() && x > nums[stack.peek()]) {res[stack.pop()] = x;}// 只有下标小于n的才入栈if (i < n) {stack.push(i);}}return res;}
}

12. 接雨水

42. 接雨水 - 力扣(LeetCode)

用了单调栈,从此接雨水可以秒了。(真的吗?)

不管怎么说,先看看暴力解法吧,也可以通过,这个是理解题目的基础

class Solution {public int trap(int[] height) {int sum = 0;for (int i = 0; i < height.length; i++) {// 第一个柱子和最后一个柱子不接雨水if (i==0 || i== height.length - 1) continue;int rHeight = height[i]; // 记录右边柱子的最高高度int lHeight = height[i]; // 记录左边柱子的最高高度for (int r = i+1; r < height.length; r++) {if (height[r] > rHeight) rHeight = height[r];}for (int l = i-1; l >= 0; l--) {if(height[l] > lHeight) lHeight = height[l];}int h = Math.min(lHeight, rHeight) - height[i];if (h > 0) sum += h;}return sum;}
}

单调栈法

class Solution {public int trap(int[] height){int size = height.length;Stack<Integer> stack = new Stack<Integer>();stack.push(0);int sum = 0;for (int index = 1; index < size; index++){int stackTop = stack.peek();if (height[index] < height[stackTop]){stack.push(index);}else if (height[index] == height[stackTop]){// 因为相等的相邻墙,左边一个是不可能存放雨水的,所以pop左边的index, push当前的indexstack.pop();stack.push(index);}else{int heightAtIdx = height[index];while (!stack.isEmpty() && (heightAtIdx > height[stackTop])){int mid = stack.pop();if (!stack.isEmpty()){int left = stack.peek();int h = Math.min(height[left], height[index]) - height[mid];int w = index - left - 1;int hold = h * w;if (hold > 0) sum += hold;stackTop = stack.peek();}}stack.push(index);}}return sum;}
}

本文的分享就到这里了,

我是此林,关注我吧,带你看不一样的世界!

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

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

相关文章

《5分钟开发订单微服务!飞算JavaAI实战:IDEA插件安装→空指针修复→K8s部署全流程》

目录 40倍提升开发效能的秘密武器 一、为什么选择飞算JavaAI&#xff1f;​编辑 二、IDEA插件安装三步曲&#xff08;极简版&#xff09; 步骤1&#xff1a;安装插件&#xff08;30秒完成&#xff09; 步骤2&#xff1a;账号登录&#xff08;2种方式任选&#xff09; 方式…

SQL注入基础尝试

进入网址&#xff0c;测试正常回显和出错画面http://1bcf75af-6e69-4f78-ac71-849fb8cde1b5.node5.buuoj.cn/Less-2/? id1用特殊符号判断注入点判断其类型类型为数字型&#xff0c;order by判断列数当数字为4时候报错而3不报错&#xff0c;由此推断列数为3&#xff0c;接着测试…

[Dify] -进阶4-在 Dify 中实现 PDF 文档问答功能全流程

随着业务需求增加,AI 应用常遇到让模型“读懂”PDF并回答问题的场景。借助 Dify 的 RAG(Retrieval‑Augmented Generation)能力,我们可以构建一个“ChatPDF”式的互动问答机器人。本文详细讲解从环境搭建、PDF 上传、文本抽取、向量检索到问答部署的完整流程。 一、技术栈与…

【EPLAN 2.9】许可证xx成功却显示红色叉,无法启动

问题现象&#xff1a; 无法启动。 原因&#xff1a;通过mstsc远程桌面连接会占用显卡&#xff0c;导致调用显卡的软件无法成功。参考&#xff1a;Windows自带远程桌面(mstsc)在远程时无法启动&#xff08;打开&#xff09;某些应用&#xff08;软件&#xff09;的解决办法 编写…

Oracle ADG 一键自动化搭建脚本

前言在 Oracle 数据库高可用架构中&#xff0c;Active Data Guard (ADG) 是保障数据安全和业务连续性的核心方案。然而传统 ADG 搭建涉及数十项复杂配置&#xff08;监听、TNSNAMES、参数文件、密码文件、日志传输、应用服务等&#xff09;&#xff0c;步骤繁琐且易错&#xff…

某邮生活旋转验证码识别

注意,本文只提供学习的思路,严禁违反法律以及破坏信息系统等行为,本文只提供思路 如有侵犯,请联系作者下架 本文识别已同步上线至OCR识别网站: http://yxlocr.nat300.top/ocr/other/30 旋转验证码数据集如下: 看起来很像顶象的,都有着绿边干扰,那其实思路也能简单了,…

基于Android的景点旅游信息系统App

项目介绍用户分为普通用户和管理员两种角色。 1.管理员有用户管理、景点管理、评论管理功能。 2.用户管理包括查看已注册用户列表、删除用户&#xff1b; 3.景点管理包括增加景点信息、修改景点信息、删除景点信息、将景点设为推荐&#xff1b; 4.评论管理包括查看评论内容、删…

Python----NLP自然语言处理(词向量与词嵌入)

一、词向量与词嵌入将文本语料分词后&#xff0c;接下来就可以让计算机学习这些词&#xff0c;理解这些词的含义。我们可以直接将文本数据输入到计算机中让计算机学习吗&#xff1f;不可以&#xff0c;计算机只能看懂数字&#xff0c;看不懂文字。所以我们需要将词语转成一串数…

八、DMSP/OLS、NPP/VIIRS等夜间灯光数据能源碳排放空间化——碳排放空间分级、空间自相关

一、前言 前面已经将反演后能源碳排放提取、增长率、Slope趋势法分析做了介绍,本节就是给大家介绍如何制作碳排放空间分级和空间自相关的一些具体操作步骤,其实网上也有比较多的各类学习资源,但是质量就层次不齐。这里就给大家详细从头到尾说明白解释清楚如何获取下图这些成…

【电脑】鼠标的基础知识

下面是一些关于鼠标的详细知识&#xff1a;鼠标的基本结构外壳&#xff1a;通常由塑料或金属制成&#xff0c;提供手握的地方。滚轮&#xff1a;位于中央&#xff0c;用于滚动页面。有些高端型号的滚轮可以自定义功能。按键&#xff1a;最常见的是左键、右键和中键&#xff08;…

A33-vstar笔记及资料分享:搭建交叉编译环境

前言 本篇主要是介绍博主在构建A33-vstar开发板镜像时的步骤&#xff0c;也踩了一些坑&#xff0c;才整理出来&#xff0c;如果有错误&#xff0c;还请指正。 A33-vstar开发板的资料&#xff1a; 通过网盘分享的文件&#xff1a;A33-Vstar开发板资料合集 链接: https://pan.bai…

基于51单片机智能家居监控系统设计

摘 要 智能家居是以住宅为平台&#xff0c;利用综合布线技术、网络通信技术、安全防范技术、自动控制技术、音视频技术将家居生活有关的设施集成&#xff0c;构建高效的住宅设施与家庭日程事务的管理系统&#xff0c;提升家居安全性、便利性、舒适性、艺术性&#xff0c;并实现…

在 OpenSUSE Tumbleweed 和 Leap 上安装 VirtualBox

OpenSUSE 是一款特别适合工作站、服务器及虚拟化环境(如 VirtualBox 和 VMware)的 Linux 发行版。虽然知名度不及 Ubuntu,但实际使用中我发现它比 CentOS、RedHat 甚至 Ubuntu 更易理解、安装和使用。当然,Ubuntu 庞大的社区支持确实使其更受欢迎。 该系统预装了 LibreOff…

Ansible AWX 自动化运维

Ansible & AWX 自动化运维一、概述1. Ansible 简介定义Ansible 是一款由 Michael DeHaan 创建的开源自动化工具&#xff0c;它基于 Python 语言开发&#xff0c;旨在简化复杂的 IT 任务&#xff0c;如配置管理、应用部署、任务编排和云资源管理等。其核心设计理念是“无代理…

如何解决服务器频繁重启的问题?

高防CDN和香港高防服务器是两种常见的网络安全解决方案&#xff0c;用于应对DDoS攻击和其他恶意流量。但它们的工作原理、应用场景和特点有所不同。以下是详细的对比分析&#xff1a;1. 什么是高防CDN和香港高防服务器&#xff1f;1.1 高防CDN高防CDN (Content Delivery Networ…

docker安装、启动jenkins服务,创建接口自动化定时任务(mac系统)

前提&#xff1a;安装Docker。 1、Docker拉取镜像、启动服务 &#xff08;可参考Jenkins官网教程&#xff1a;安装Jenkins&#xff09; 1. 从Docker Hub下载最新的Jenkins LTS&#xff08;长期支持&#xff09;镜像&#xff1a; docker pull jenkins/jenkins:lts2. 使用Doc…

板凳-------Mysql cookbook学习 (十一--------12)

第16章&#xff1a;使用存储例程、触发器和事件 16.0 引言 mysql> -- 首先设置分隔符&#xff08;避免分号被解释为语句结束&#xff09; mysql> DELIMITER // mysql> mysql> -- 创建第一个存储过程 mysql> CREATE PROCEDURE get_time()-> BEGIN-> SE…

linux端口监听命令

端口监听命令&#xff1a; netstat -nlp&#xff5c;grep 86886 netstat -nlp&#xff5c;grep 8686 netstat -nlp&#xff5c;grep 8686 netstat -nl&#xff5c;grep 8686 netstat -n&#xff5c;grep 8686各命令的含义与区别&#xff1a; 1. netstat -nlp | grep 86886 参数…

APP端定位实现(uniapp Vue3)(腾讯地图)

一.申请腾讯地图开发者 官网腾讯位置服务 - 立足生态&#xff0c;连接未来 注册的话可以选择个人和企业,推荐先注册个人,企业的话如果后期有需要到时候个人可以升级为企业 申请完成之后点击控制台进入当前页面后点击应用管理 —— 我的应用 点击创建应用 应用名称随便填(自己知…

Linux之Zabbix分布式监控篇(二)

一、前置回顾zabbix作为一个分布式监控工具&#xff0c;能帮助我们7*24*365监控硬件使用情况&#xff08;cpu,内存&#xff09;&#xff0c;以及网络流量波动&#xff0c;从而能让运维能及时排查错误zabbix由zabbix-server(10051)、zabbix-agent(10050)、zabbix-database、zabb…