代码随想录day10

图像处理基础 || (一) python 读取图像的常用方式 图像的读取与保存是图像处理或计算机视觉领域中最基本的操作,python中有众多的库支持图像的读取、显示与存储,常用的库包括 matplotlib、skimage 和 Pillow 库。 阅读详情

第五章 栈与队列part01

理论基础

文章讲解:代码随想录

232.用栈实现队列

题目链接/文章讲解/视频讲解:代码随想录

225. 用队列实现栈

题目链接/文章讲解/视频讲解:代码随想录

20. 有效的括号

题目链接/文章讲解/视频讲解:代码随想录

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

题目链接/文章讲解/视频讲解:代码随想录

理论基础

栈

在Java中,“栈”这个术语通常指的是与方法调用相关的数据结构。在Java虚拟机(JVM)中,栈主要分为两种不同的类型:

  1. 虚拟机栈 (Virtual Machine Stack)
  2. 本地方法栈 (Native Method Stack)

虽然“方法栈”这个词不是官方术语,但我们可以理解为你所指的就是“虚拟机栈”,因为它确实用于支持Java方法的执行。接下来我将详细解释这两种栈的区别:

1. 虚拟机栈 (Virtual Machine Stack)

虚拟机栈是为每个线程创建的,用于存储线程的局部变量、部分结果以及方法调用的信息。每当一个线程开始执行时,JVM就会为该线程创建一个虚拟机栈。虚拟机栈中的每一个元素称为一个栈帧(Stack Frame),每个栈帧对应一个方法调用。

  • 栈帧:每个方法调用都会生成一个栈帧,包含以下部分:
    • 局部变量表 (Local Variable Table):用于存放方法参数和局部变量。
    • 操作数栈 (Operand Stack):用于存放中间计算结果。
    • 动态链接 (Dynamic Link):用于支持方法调用过程中将常量池中的符号引用转换为直接引用。
    • 返回地址 (Return Address):记录方法返回时需要跳转的位置。

2. 本地方法栈 (Native Method Stack)

本地方法栈与虚拟机栈类似,但它用于支持本地方法(即使用本地代码实现的方法,通常是C/C++实现的JNI方法)的执行。本地方法栈和虚拟机栈的主要区别在于它们支持的代码类型不同。虚拟机栈支持的是Java字节码,而本地方法栈支持的是本地平台的机器代码。

  • 栈帧:本地方法栈中的栈帧也包含与方法调用相关的信息,但由于执行的是本地代码,因此具体的栈帧布局可能与虚拟机栈有所不同。

区别总结

  • 用途:

    • 虚拟机栈:用于支持Java方法的执行。
    • 本地方法栈:用于支持本地方法的执行。
  • 数据类型:

    • 虚拟机栈:处理的是Java字节码。
    • 本地方法栈:处理的是本地代码(例如C/C++)。
  • 实现方式:

    • 虚拟机栈:由JVM实现。
    • 本地方法栈:通常由操作系统提供的栈实现。

实例说明

假设有一个Java程序,其中包含了一个本地方法调用:

public class StackExample {
    public static void main(String[] args) {
        System.out.println("In main method");
        methodA();
    }

    public static void methodA() {
        System.out.println("In methodA");
        nativeMethod();
    }

    public static native void nativeMethod();
}

在这个例子中,当执行 methodA() 时,程序的执行流程如下:

  1. 主方法 (main) 的栈帧被压入虚拟机栈。
  2. methodA 的栈帧被压入虚拟机栈的栈顶。
  3. nativeMethod 被调用,此时,一个栈帧会被压入本地方法栈。
  4. nativeMethod 执行完毕后,其栈帧从本地方法栈中弹出。
  5. methodA 继续执行直至完成,其栈帧从虚拟机栈中弹出。
  6. main 方法继续执行直至完成。

虚拟机栈和本地方法栈的主要区别在于它们支持的方法类型和实现机制。虚拟机栈用于Java方法的执行,而本地方法栈用于本地方法的执行。两者都在方法调用时创建栈帧来存储相关信息。

队列

  • 栈:在Java中,栈是一种由JVM自动管理的数据结构,用于支持线程和方法调用。
  • 队列:队列是一种程序员可以显式创建和使用的数据结构,通过Java标准库中的Queue接口和其实现类来实现。

232.用栈实现队列

思路

栈只能实现元素的一端进出,而队列是要求一端进一端出,但进到栈底的元素无法出来,这时就需要另一个栈来辅助,如下图

关键点在于要判断栈2是否为空,否则会影响到下次操作,同时要把全部栈1push到栈2中

class MyQueue {

    Stack<Integer> stackIn;
    Stack<Integer> stackOut;

    /** Initialize your data structure here. */
    public MyQueue() {
        stackIn = new Stack<>(); // 负责进栈
        stackOut = new Stack<>(); // 负责出栈
    }
    
    /** Push element x to the back of queue. */
    public void push(int x) {// 加入元素,即将元素 x 推到队列的末尾
        stackIn.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    public int pop() {    //删除元素
        dumpstackIn();
        return stackOut.pop();
    }
    
    /** Get the front element. */
    public int peek() {//返回队列开头的元素
        dumpstackIn();
        return stackOut.peek();
    }
    
    /** Returns whether the queue is empty. */
    public boolean empty() {
        return stackIn.isEmpty() && stackOut.isEmpty();
    }

    // 如果stackOut为空,那么将stackIn中的元素全部放到stackOut中
    private void dumpstackIn(){
        if (!stackOut.isEmpty()) return; 
        while (!stackIn.isEmpty()){
                stackOut.push(stackIn.pop());
        }
    }
}

225. 用队列实现栈

思路

同时也可以用两个队列来模拟栈,比较容易,这里还是用以一个队列来模拟栈

import java.util.LinkedList;
import java.util.Queue;

class MyStack {
    // 使用LinkedList作为队列的底层实现
    private Queue<Integer> queue;
    
    // 构造函数:初始化一个空的队列
    public MyStack() {
        queue = new LinkedList<>();
    }
    
    // push方法:将一个元素添加到队列中
    // 由于队列遵循先进先出的原则,这里的操作实际上模拟了栈的后进先出行为
    public void push(int x) {
        queue.add(x); // 将元素添加到队列尾部
    }
    
    // pop方法:从队列中移除并返回队列头部的元素
    // 为了模拟栈的行为,我们需要先将队列中的所有元素除了最后一个以外都重新定位到队列尾部
    public int pop() {
        rePosition(); // 重新定位队列中的元素
        return queue.poll(); // 从队列头部移除并返回元素
    }
    
    // top方法:返回队列头部的元素,但不移除它
    // 为了模拟栈的行为,我们同样需要先重新定位队列中的元素
    public int top() {
        rePosition(); // 重新定位队列中的元素
        int result = queue.poll(); // 从队列头部获取元素
        queue.add(result); // 将元素重新添加到队列尾部,以保持队列的状态不变
        return result; // 返回头部元素
    }
    
    // empty方法:检查队列是否为空
    public boolean empty() {
        return queue.isEmpty(); // 检查队列是否为空
    }

    // rePosition方法:重新定位队列中的元素,除了最后一个以外的所有元素都要移动到队列尾部
    // 这样做的目的是为了让队列的头部始终是栈顶元素
    public void rePosition(){
        int size = queue.size(); // 获取队列的大小
        size--; // 减去1,因为我们最终要保留最后一个元素在队列头部
        while(size-->0) { // 循环直到只剩下最后一个元素
            queue.add(queue.poll()); // 从队列头部移除元素并添加到队列尾部
        }
    }
}

20. 有效的括号

思路

考虑不匹配的情况:

  1. 数量不匹配:左括号多余、右括号多余
  2. 括号数量匹配但类型不匹配

遇到左括号在栈弹入右括号(方便直接判断),当遇到右括号直接进行比较

class Solution {
    public boolean isValid(String s) {
        Deque<Character> deque = new LinkedList<>();
        char ch;
        for (int i = 0; i < s.length(); i++) {
            ch = s.charAt(i);
            //碰到左括号,就把相应的右括号入栈
            if (ch == '(') {
                deque.push(')');
            }else if (ch == '{') {
                deque.push('}');
            }else if (ch == '[') {
                deque.push(']');
            } else if (deque.isEmpty() || deque.peek() != ch) {
                return false;
            }else {//如果是右括号判断是否和栈顶元素匹配
                deque.pop();
            }
        }
        //最后判断栈中元素是否匹配
        return deque.isEmpty();
    }
}

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

栈的作用与上一题相似,存储遍历过的元素,比较下一个元素是否和上一个存储的元素相同

运行速度:双指针<字符串<栈

栈方法

class Solution {
    public String removeDuplicates(String S) {
        //ArrayDeque会比LinkedList在除了删除元素这一点外会快一点
        //参考:https://stackoverflow.com/questions/6163166/why-is-arraydeque-better-than-linkedlist
        ArrayDeque<Character> deque = new ArrayDeque<>();
        char ch;
        for (int i = 0; i < S.length(); i++) {
            ch = S.charAt(i);
            if (deque.isEmpty() || deque.peek() != ch) {
                deque.push(ch);
            } else {
                deque.pop();
            }
        }
        String str = "";
        //剩余的元素即为不重复的元素
        while (!deque.isEmpty()) {
            str = deque.pop() + str;
        }
        return str;
    }
}

拓展方法1-字符串

class Solution {
    public String removeDuplicates(String s) {
        // 将 res 当做栈
        // 也可以用 StringBuilder 来修改字符串,速度更快
        // StringBuilder res = new StringBuilder();
        StringBuffer res = new StringBuffer();
        // top为 res 的长度
        int top = -1;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            // 当 top > 0,即栈中有字符时,当前字符如果和栈中字符相等,弹出栈顶字符,同时 top--
            if (top >= 0 && res.charAt(top) == c) {
                res.deleteCharAt(top);
                top--;
            // 否则,将该字符 入栈,同时top++
            } else {
                res.append(c);
                top++;
            }
        }
        return res.toString();
    }
}

拓展方法2-双指针

class Solution {
    public String removeDuplicates(String s) {
        char[] ch = s.toCharArray();
        int fast = 0;
        int slow = 0;
        while(fast < s.length()){
            // 直接用fast指针覆盖slow指针的值
            ch[slow] = ch[fast];
            // 遇到前后相同值的,就跳过,即slow指针后退一步,下次循环就可以直接被覆盖掉了
            if(slow > 0 && ch[slow] == ch[slow - 1]){
                slow--;
            }else{
                slow++;
            }
            fast++;
        }
        return new String(ch,0,slow);
    }
}

【异常】OpenClaw LLM请求超时故障全链路排查与解决方案 LLM request timed out. 网络连接超时了 摘要: OpenClaw LLM请求超时故障是高频网络交互问题,表现为客户端在预设时间内未收到服务端响应。根因分为四类:客户端配置缺陷(如超时阈值不合理)、网络链路异常(防火墙拦截等)、服务端问题(限流/宕机)及硬件瓶颈(算力不足)。解决方案分三步: 通用排查:检查网络连通性、关闭防火墙/代理校验,调整超时阈值至60-300秒; 分场景修复:云端API需核对密钥/限流规则,本地部署需验证服务状态与硬件资源; 兜底方案:重启程序、更新版本或更换服务端点,结合日志精准定位。修复后不影响OpenClaw数据完整性 阅读详情

相关推荐

我的AI学习 ai维护工具之langfuse

as_type: Optional[Literal[‘generation’]] = None, # 将记录定义为 Observation (LLM 调用)transform_to_string: Optional[Callable[[Iterable], str]] = None # 将输出转为 string。要用LangFuse的云服务,首先要在LangFuse官网上注册,注册完后将页面拉倒最后,点免费的SignUp,API文档:https://api.reference.langfuse.com/

liubaobin的博客 4095

网站收藏箱

文章内容都是笔者日常工作与学习接触到,并且觉得不错的网站,特收录在册,欢迎广大读者提供补充,文章会持续更新

沉梦听雨的博客 1万+

IBM 3560M3 R5 坏盘更换记录

公司一台老旧 3650M3在日常巡查过程中发现硬盘报错

ddriv的博客 3944

算法速成之代码随想录

有些同学想要学习算法题,但是时间很紧,自己的基础也不是很好,想要在空余时间完全掌握所有算法题确实有点不切实际了,终于去学习了遇到难题又半途而废,于是我总结了一下刷代码随想录题目的方法先看b站视频:BV1fA4y1o715,有规划的看,每一类题可以看一到两道,看完去做题,感觉基本了解了就可以直接看代码随录博客的题目跟着做,因为看视频较为费时间,博客中的注释非常详细;写题时候,,实在无从下手就他的,看完应该都能自己写了,如果连思路都看不懂,那么就求助gpt或者去看他的视频;每周写题也要有一定的规划,

qq_63728673的博客 7032

C#与海康威视工业相机结合OpenCV与WPF:打造高效的机器视觉应用程序

本文介绍了基于C#、海康威视工业相机SDK和OpenCV的机器视觉应用开发方法。首先配置开发环境,包括海康SDK、OpenCvSharp和WPF项目设置。重点阐述了如何通过SDK初始化相机、获取视频流,并将YUV数据转换为OpenCV可处理的Mat格式进行图像处理(如边缘检测)。同时展示了如何用WPF实现界面交互和实时图像显示。该方案为工业自动化、质量检测等场景提供了高效的技术实现路径,结合了海康相机的高性能采集、OpenCV的强大算法和WPF的交互优势,具有较高的实用价值。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1498

Vue3 - Vite运行打包时Uncaught ReferenceError: process is not defined(解决vue3+vite报错process is not defined)

vue3,vite,vue3+vite报错,process,UncaughtReferenceError:processisnotdefined,浏览器控制台报错processisnotdefined解决方法,vue3如何解决报错,vite报错怎么办,前端打包UncaughtReferenceError:processisnotdefined,npmrunbuild打包报错,vite打包时出现错误,vue3打包运行找不到process,热更新会报错UncaughtRefer

🏆 前端领域优质创作者 7737

代码随想录刷题笔记 (python版本) 持续更新.....

代码随想录刷题笔记

hello world 1万+

PCB制造工艺参数到AD规则设置

本文提供了PCB设计与制造的落地指南,强调需先了解PCB厂的工艺参数,再在Altium Designer中设置相应规则。核心步骤包括:获取PCB厂的关键工艺参数(线宽/线距、过孔尺寸等),在AD中设置电气规则、布线规则、阻焊规则等,并进行DRC检查。文章还给出了常见问题避坑建议和快速落地模板,帮助设计师确保设计符合生产要求,避免因工艺不匹配导致的报废或成本增加。

qq_37999850的博客 293

【leetcode刷题总结】——代码随想录(链表总结)

什么是链表,链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。

lingxw的博客 4942

cuRobo 入门教程(二)基于CUDA的机器人运动规划加速库

cuRobo是一款基于CUDA加速的机器人算法库,提供正向/逆向运动学、碰撞检测、数值优化等核心功能,支持在NVIDIA Jetson Orin等平台上实现毫秒级运动规划。该库创新性地采用并行轨迹优化技术,结合nvblox工具实现深度摄像头避障功能,并通过多层ESDF结构处理动态障碍物。性能测试显示,在RTX 6000 Ada显卡上可实现99.85%的成功率,平均规划时间仅39毫秒。cuRobo还提供Python API支持神经网络集成,并具备批量环境处理能力,特别适用于工业机器人应用场景。最新版本通过算法

2506_90492529的博客 1303

vue:npm安装pnpm报错,npm ERR! code ENOTFOUND,npm ERR! syscall getaddrinfo,npm ERR! errno ENOTFOUND详细排查解决!

vue2 vue3,npm install -g pnpm 安装出现错误,安装pnpm及解决安装失败问题,解决 npm无法安装pnpm问题,npm 安装 pnpm 时 报错 npm ERR! code ENOTFOUND,pnpm无法安装报错,vue npm install -g pnpm安装报错,request to http://registry.cnpmjs.org/pnpm failed, reason: getaddrinfo ENOTFOUND registry.cnpmjs.org,安装pnp

✅ 精选推荐文章 3608

LeetCode代码随想录

代码随想录 (programmercarl.com) java 35.搜索插入位置 34.在排序数组中查找元素的第一个和最后一个位置 java 69.X的平方根 java java 27移除元素 c++ java 283.移动零 java 844.比较含退格的字符串 java:双指针版 java:栈版 97.有序数组的平方 c++ java

死也不承认自己笨的博客 2634

RH850从0搭建Autosar开发环境【3X】- Davinci Configurator之OS模块配置详解(中)

RH850从0搭建Autosar开发环境【3X】- Davinci Configurator之OS模块配置详解(中)

weixin_42412049的博客 1515

代码随想录Day10

根据 逆波兰表示法,求表达式的值。有效的运算符包括 + , - , * , /。每个运算对象可以是整数,也可以是另一个逆波兰表达式。说明:整数除法只保留整数部分。给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。题目思路:这道题属于是老题新做了,是一道很经典的使用栈结构来解决的问题,核心思路就是遇到运算符时弹出栈顶的前两个做对应的运算,再将对应的运算结果压回栈等待下一次运算,最后返回栈顶的元素就是就是运算的结果AC代码。

HNTZB的博客 739

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

代码随想录带刷day10

例如,在 “abbaca” 中,我们可以删除 “bb” 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。解析:本题题目描述不明确,导致有些情况没想到,初始时看测试用例,感觉可以hash来做,这样能大大节约时间,但是,最后发现测试用例没过,之后去看了。你所使用的语言也许不支持栈。题目描述:给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。题目描述:给出由小写字母组成的字符串 s,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

qq_64919637的博客 755

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

代码随想录day10 栈与队列part01

这部分本该是昨日的内容,昨日字节面试意外还可以,总结2点。尚未涉及技术性问题,这里不是要你把之前背的八股文说的多么详细,最好还是能够结合公司的具体产品,去做一个理解性的说明。比如字节的飞书,抖音,豆包产品;腾讯的微信,QQ,游戏等。面试官也希望听到新颖的东西。复盘完毕,开始补内容:今日是栈、队列相关内容:理解栈的作用的典型场景典型场景:①匹配括号,验证完整性;②后缀表达式——、计算器中带括号的运算规则通常基于栈(Stack)和后缀表达式(逆波兰表示法,RPN)的组合来实现。后缀表达式应用栈的原则。

Gewe_Xiaokang的博客 650

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

代码随想录刷题Day10

这9天慢慢养成刷题习惯,对数组经典问题类型:二分、双指针、移动窗口、模拟螺旋矩阵、数组前缀和,基本过了一遍。二分,前提是数组是有序的,除了用来在数组中按值搜索外,还能加速自然数(自然有序)一些求解过程,比如不用调函数库的方式求解数的平方根;双指针,重要的是定义好两个指针的目的,一般是一个指针用来遍历数组,一个指针是用来处理和题目有关的事情,比如删除数组任务中,维护删除后的指针位置,或者是移动0时维护非零部分等。

qq_57141819的博客 692

Day10 代码随想录 刷题记录

共刷3题,总计用时5h25mins。6.3开始进入旅游状态,休息了几天,零零散散敲了点代码,看了下整体的思路。后面应该要更加大强度,同时跟进相关基础知识的学习。

windyyyyyyyyyyy的博客 899

代码随想录五刷day10

动态规划

ResNet156的博客 1135

代码随想录算法训练营Day10

【代码】代码随想录算法训练营Day10。

lololo的博客 579

代码随想录Day 10

我不受限制,我使我自己自由,我走到我所愿去的任何地方。232.用栈实现队列225. 用队列实现栈。

free_puppy的博客 270

代码随想录day10 -- 栈与队列

一开始漏了划线部分,这里不能省略,只有当out全部弹出时,才能在进行out.push(in.top()),不然弹出顺序会乱(后进先出)思路:选择把左括号或者右括号入栈,然后在进行匹配。(我写的是左括号入栈,卡哥是右括号入栈,两种都可以)有点像负负得正的感觉,大体就是利用两个栈套娃般的操作就可以模拟队列了。其实就是把队列的末尾变成队头(队列的末尾就是要弹出的),然后弹出就可以了,然后。用一个队列就够了,pop和top是这题的重点(实现起来也一模一样),思路:用栈存储,遍历入栈,当有重复的就出栈,反之入栈。

W94789888的博客 728

力扣225 代码随想录Day10 第二题

【代码】力扣225 代码随想录Day10 第二题。

2301_80653171的博客 193

代码随想录刷题day10

的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的。感悟:遇到运算符,取运算符前两位进行计算,利用了栈后进先出的原理。感悟:维护一个单调队列,队列中元素为单调递增或者单调递减。返回一个表示表达式值的整数。滑动窗口每次只向右移动一位。1、逆波兰表达式求值。

LL_xjbt的博客 322

力扣20 代码随想录Day10 第三题

【代码】力扣20 代码随想录Day10 第三题。

2301_80653171的博客 230
上一篇: 代码随想录day9
下一篇: 代码随想录day11
cookieeee_
博客等级 码龄4年 189粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值