当前位置: 首页 > news >正文

算法沉淀一:双指针

目录

前言:

双指针介绍

对撞指针

快慢指针

题目练习

1.移动零

2.复写零

3.快乐数

4.盛水最多的容器

5.有效三角形的个数

6.和为s的两个数

7.三数之和

8.四数之和


前言:

此章节介绍一些算法,主要从leetcode上的题来讲解,讲解内容为做题思路,附加代码。

欢迎与我大家一起学习共同进步!沉淀!passion!

双指针介绍

双指针的常见形式有两种:对撞指针,快慢指针。

对撞指针

  • 对撞指针也称为左右指针,一个在最左边,一个在最右边,逐渐往中间逼近。
  • 对撞指针的终止条件一般是两个指针相遇或者是错开,也有可能是找到了结果直接跳出循环。

        left == right (两个指针指向同⼀个位置)

        left  >  right (两个指针错开)

快慢指针

其基本思想就是使用两个移动速度不同的指针在数组链表等序列结构上移动。这种方法对于处理环形链表数组非常有用。其实不单单是环形链表或者是数组,如果我们要研究的问题出现循环往复的情况时,均可考虑使用快慢指针的思想。快慢指针的实现方式有很多种,最常用的⼀种就是:

• 在⼀次循环中,每次让慢的指针向后移动⼀位,而快的指针往后移动两位,实现⼀快⼀慢。

题目练习

1.移动零

leetcode题目链接

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:输入: nums = [0,1,0,3,12]  输出: [1,3,12,0,0]

示例 2:输入: nums = [0]      输出: [0]

解法(快排的思想:数组划分区间 - 数组分两块):

算法思路:

cur 从前往后遍历的过程中:

1、遇到0                    cur++;

2、遇到非0元素          swap(dest+1,cur)      dest++,cur++; 

class Solution {
public:void moveZeroes(vector<int>& nums) {for(int cur = 0, dest = -1; cur < nums.size(); cur++)if(nums[cur]) // 处理⾮零元素swap(nums[++dest], nums[cur]);}
};

2.复写零

leetcode题目链接

给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。

注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。

示例 1:输入:arr = [1,0,2,3,0,4,5,0] 输出:[1,0,0,2,3,0,0,4]

解释:调用函数后,输入的数组将被修改为:[1,0,0,2,3,0,0,4]

示例 2:输入:arr = [1,2,3]                输出:[1,2,3]

解释:调用函数后,输入的数组将被修改为:[1,2,3]

解法:

先根据“异地”操作,然后优化成双指针下的“就地”操作。异地就是再开辟一个数组,cur遇到非0,dest复制下来,是0的话,就复写两边。但是现在是要就地操作,cur和dest都放在同一个数组,如果从前往后,直接复写的话,复写会覆盖后面的元素。所以考虑从后往前操作。

1、先找到最后一个”复写“的数

        双指针算法   cur = 0,  dest = -1

                1.先判断cur的位置的值

                2.决定dest向后移动一步或者两步

                3.判断一下dest是否已经到结束为止

                4.cur++

                5.处理边界情况:[ 1,0,2,3,0,4]

                        n-1 == 0

                        cur--

                        dest -= 2

2、”从后向前“完成复写操作

代码:

class Solution {
public:void duplicateZeros(vector<int>& arr) {int n = arr.size(), cur = 0, dest = -1;//找到最后一个复写元素while (cur < n){if (arr[cur]) dest++;else dest += 2;if (dest >= n - 1) break;cur++;}//2.处理边界情况if (dest == n){arr[n - 1] = 0;cur--;dest -= 2;}//3.从后往前完成复写操作while (cur >= 0){if (arr[cur]) arr[dest--] = arr[cur--];else{arr[dest--] = 0;arr[dest--] = 0;cur--;}}}
};

3.快乐数

leetcode题目链接

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

示例 1:输入:n = 19 输出:true

解释: 12 + 92 = 82 82 + 22 = 68 62 + 82 = 100 12 + 02 + 02 = 1

示例 2:输入:n = 2 输出:false

示例1的解释,就是每位数的平方相加,最后等于1

示例2则是  2 - 4 - 16 - 37 - 58 - 89 - 145 - 42 - 20 - 4 最后会变成这些数其中的一位,跟链表中的环形链表相似,我们则可以把它抽象成环形链表相遇的问题,当相遇的时候,bool值不是1,则不是快乐数。是1,则是快乐数。

class Solution
{
public:int bitSum(int n) // 返回 n 这个数每⼀位上的平⽅和{int sum = 0;while (n){int t = n % 10;sum += t * t;n /= 10;}return sum;}bool isHappy(int n){int slow = n, fast = bitSum(n);while (slow != fast){slow = bitSum(slow);fast = bitSum(bitSum(fast));}return slow == 1;}
};

4.盛水最多的容器

leetcode题目链接

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。

示例 1:输入:[1,8,6,2,5,4,8,3,7] 输出:49

解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例 2:输入:height = [1,1] 输出:1

class Solution {
public:int maxArea(vector<int>& height) {int left = 0, right = height.size() - 1, ret = 0;while (left < right){int v = min(height[left], height[right])*(right - left);ret = max(ret, v);//记录最大容器面积if (height[left] < height[right]) left++;//最小的数组决定水桶的最大容积else right--;}return ret;}
};

5.有效三角形的个数

leetcode题目链接

给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。

示例 1:输入: nums = [2,2,3,4] 输出: 3

解释:有效的组合是: 2,3,4 (使用第一个 2) 2,3,4 (使用第二个 2) 2,2,3

示例 2:输入: nums = [4,2,3,4] 输出: 4

class Solution {
public:int triangleNumber(vector<int>& nums) {sort(nums.begin(), nums.end());int ret = 0;//记录有多少个三角形int n = nums.size();for (int i = n - 1; i >= 2; i--) {int left = 0;int right = i - 1;while (left < right) {if (nums[left] + nums[right] > nums[i]){ret += right - left;right--;}else left++;}}return ret;}
};

6.和为s的两个数

leetcode题目链接

购物车内的商品价格按照升序记录于数组 price。请在购物车中找到两个商品的价格总和刚好是 target。若存在多种情况,返回任一结果即可。

示例 1:输入:price = [3, 9, 12, 15], target = 18               输出:[3,15] 或者 [15,3]

示例 2:输入:price = [8, 21, 27, 34, 52, 66], target = 61 输出:[27,34] 或者 [34,27]

解法思路: 

首先肯定想的就是暴力枚举,双重循环。其实很多方法都是在暴力枚举上进行优化的。此题一样可以优化。

观察题目可知,要得出 target ,那么在两数相加(sum)时,就得有三种判断,

target > sum  ---->  sum++

target < sum  ---->  sum--

target = sum  ---->  return{left,right}

我们顺着这个思路来,既然是两数,使用双指针(对撞指针),一个在最左边,一个在最右边,如果两个指针发生了对撞,那么就证明这个数组中是没有答案的。

class Solution {
public:vector<int> twoSum(vector<int>& price, int target) {int n = price.size();int left = 0, right = n -1;while(left<right){int sum = price[left] + price[right];if (sum == target){return {price[left],price[right]};}else if(sum > target){right--;}else{left++;}}return {0,0};}
};

7.三数之和

leetcode题目链接

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]]

解释:

nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。

nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。

nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。

不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。 注意,输出的顺序和三元组的顺序并不重要。

示例 2:输入:nums = [0,1,1] 输出:[]

解释:唯一可能的三元组和不为 0 。

示例 3:输入:nums = [0,0,0] 输出:[[0,0,0]]

解释:唯一可能的三元组和为 0 。

想法思路:

其实做这个题目可以在上一个题目的基础下来建立思路,这是一个三数之和相加为0,上一题是两数相加为0。那么多出来的一个数,则就可以看成是另外两个数之和的相反数。两数相加为sum,还有一个数则为-sum,如果这两个条件成立的情况下,那么就是三数之和的答案,但是还需要去重,这题难在去重。

解法步骤:

1.暴力枚举(排序+枚举+利用容器去重)(O^3)

2.优化(排序+双指针)

  •         排序
  •         固定一个数sum
  •         利用双指针left和right在后面区间找到相加 == -sum的两个数

3.处理细节问题

        去重(利用set,但是这里利用其他方法)(考虑越界问题)

                1.left 和 right 跳过相同的元素

                2.sum也要跳过相同的元素

        不漏

               找到一种结果后不要停,继续缩小区间 

解法思路: 

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> ret;//存储三数之和等于0的三个数组,二维数组//排序sort(nums.begin(), nums.end());//用双指针int n = nums.size();for (int i = 0; i < n;){if (nums[i] > 0) break;int left = i + 1, right = n - 1, target = -nums[i];	//确定基数targetwhile (left < right){int sum = nums[left] + nums[right];if (sum > target) right--;//while() 去重,再添加这一步也可以else if (sum < target) left++;//while() 去重,再添加这一步也可以else {ret.push_back({ nums[i],nums[left],nums[right] });left++, right--;//这连个while只能写在这个if里面,因为其他两个条件分别对left/right 单独进行操作,而这里是对两个都进行了操作,如果放在外面的话,可能导致越界访问的情况。while (left < right && nums[left] == nums[left - 1]) left++;//去重leftwhile (left < right && nums[right] == nums[right + 1])right--;//去重right}}//去重基数nums[i]i++;while (i < n && nums[i] == nums[i - 1]) i++;}return ret;}
};

8.四数之和

leetcode题目链接

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

  • 0 <= a, b, c, d < n
  • abc 和 d 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按 任意顺序 返回答案 。

示例 1:输入:nums = [1,0,-1,0,-2,2], target = 0 输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]

示例 2:输入:nums = [2,2,2,2,2], target = 8 输出:[[2,2,2,2]]

这题的解法和三数之和的解法一样,只是多定义了一个基数而已。没有本质上的区别。 

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> ret;sort(nums.begin(),nums.end());int n = nums.size();//定第一个基数for (int i = 0; i < n;){for (int j = i + 1; j < n;)//第二个基数{int left = j + 1, right = n - 1;long long aim = (long long)target - nums[i] - nums[j];while (left < right){int sum = nums[left] + nums[right];if (sum > aim) right--;//while() 去重else if (sum < aim) left++;//wihle() 去重else{ret.push_back({nums[i],nums[j],nums[left],nums[right]});left++, right--;//去重双指针,只能在sum == aim 里,这两步才能写,不然没有进来的话,if/else if都只是对left/right进行了操作,另外一个可能导致越界访问while (left < right && nums[left] == nums[left - 1]) left++;while (left < right && nums[right] == nums[ right + 1]) right--;}}//去重第二个数j++;while (j < n && nums[j] == nums[j - 1]) j++;}//去重第一个数i++;while (i < n && nums[i] == nums[i - 1]) i++;}return ret;}
};

相关文章:

算法沉淀一:双指针

目录 前言&#xff1a; 双指针介绍 对撞指针 快慢指针 题目练习 1.移动零 2.复写零 3.快乐数 4.盛水最多的容器 5.有效三角形的个数 6.和为s的两个数 7.三数之和 8.四数之和 前言&#xff1a; 此章节介绍一些算法&#xff0c;主要从leetcode上的题来讲解&#xff…...

Word_小问题解决_1

1.第二页是空白的&#xff0c;但是删不掉 将鼠标弄到第二页最开始的地方打开段落设置行距为固定值0.7磅 2.表格中有文字进入了表格中怎么办 打开段落&#xff0c;将缩进改为0即可...

基于opencv制作GUI界面

可以基于cvui头文件实现一些控件操作&#xff0c;头文件及demo实例 这是一个demo main.cpp #include <opencv2/opencv.hpp> #define CVUI_IMPLEMENTATION #include "cvui.h"#define WINDOW_NAME "CVUI Hello World!"int main(void) {cv::Mat frame…...

微服务即时通讯系统的实现(客户端)----(2)

目录 1. 将protobuf引入项目当中2. 前后端交互接口定义2.1 核心PB类2.2 HTTP接口定义2.3 websocket接口定义 3. 核心数据结构和PB之间的转换4. 设计数据中心DataCenter类5. 网络通信5.1 定义NetClient类5.2 引入HTTP5.3 引入websocket 6. 小结7. 搭建测试服务器7.1 创建项目7.2…...

QT使用libssh2库实现sftp文件传输

本篇文章通过用户名和密码来连接服务器端,通过密匙连接服务器端可以参考另外一篇文章: https://blog.csdn.net/u012372584/article/details/143826199?sharetype=blogdetail&sharerId=143826199&sharerefer=PC&sharesource=u012372584&spm=1011.2480.3001.…...

【Linux】进程的优先级

进程的优先级 一.概念二.修改优先级的方法三.进程切换的大致原理&#xff1a;四.上下文数据的保存位置&#xff1a; 一.概念 cpu资源分配的先后顺序&#xff0c;就是指进程的优先权&#xff08;priority&#xff09;。 优先权高的进程有优先执行权利。配置进程优先权对多任务环…...

python实现十进制转换二进制,tkinter界面

目录 需求 效果 代码实现 代码解释 需求 python实现十进制转换二进制 效果 代码实现 import tkinter as tk from tkinter import messageboxdef convert_to_binary():try:# 获取输入框中的十进制数decimal_number int(entry.get())# 转换为二进制binary_number bin(de…...

电子应用设计方案-12:智能窗帘系统方案设计

一、系统概述 本设计方案旨在打造便捷、高效的全自动智能窗帘系统。 二、硬件选择 1. 电机&#xff1a;选用低噪音、扭矩合适的智能电机&#xff0c;根据窗帘尺寸和重量确定电机功率&#xff0c;确保能平稳拉动窗帘。 2. 轨道&#xff1a;选择坚固、顺滑的铝合金轨道&…...

力扣 回文链表-234

回文链表-234 const int N 1e55; int a[N];//定义一个整形的全局数组作为辅助数组存储链表反转前的值 class Solution { /*本题的解题思路是先将链表中每个值存储到辅助数组a中&#xff0c;然后反转链表&#xff0c; 最后&#xff0c;反转后链表的值和没反转之前的值&#xf…...

采样率22050,那么CHUNK_SIZE 一次传输的音频数据大小设置多少合适?unity接收后出现卡顿的问题的思路

在采样率为22050的情况下&#xff0c;选择合适的 CHUNK_SIZE 主要取决于 Unity 接收和处理音频数据的效率。以下是设置 CHUNK_SIZE 的一些建议&#xff1a; 计算 CHUNK_SIZE&#xff1a;音频的传输数据量可以通过公式 CHUNK_SIZE 采样率 * 传输间隔秒数 * 每样本字节数 * 声道…...

网络初识--Java

一、网络通信基础 1.IP地址 IP地址主要⽤于标识⽹络主机、其他⽹络设备&#xff08;如路由器&#xff09;的⽹络地址。简单说&#xff0c;IP地址⽤于定位主 机的⽹络地址。 就像我们发送快递⼀样&#xff0c;需要知道对⽅的收货地址&#xff0c;快递员才能将包裹送到⽬的地。…...

K8S单节点部署及集群部署

1.Minikube搭建单节点K8S 前置条件&#xff1a;安装docker&#xff0c;注意版本兼容问题 # 配置docker源 wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo# 安装docker环境依赖 yum install -y yum-utils device-m…...

GPIO相关的寄存器(重要)

目录 一、GPIO相关寄存器概述 二、整体介绍 三、详细介绍 1、端口配置低寄存器&#xff08;GPIOx_CRL&#xff09;&#xff08;xA...E&#xff09; 2、端口配置高寄存器&#xff08;GPIOx_CRH&#xff09;&#xff08;xA...E&#xff09; 3、端口输入数据寄存器&#xff…...

OpenCV基础

1. 基础入门&#xff1a;OpenCV概念与安装 a. OpenCV简介 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉库&#xff0c;广泛应用于图像和视频处理、计算机视觉、机器学习等领域。 b. 安装OpenCV Python安装&#xff1a; pip in…...

两行命令搭建深度学习环境(Docker/torch2.5.1+cu118/命令行美化+插件),含完整的 Docker 安装步骤

深度学习环境的配置过于繁琐&#xff0c;所以我制作了两个基础的镜像&#xff0c;希望可以帮助大家节省时间&#xff0c;你可以选择其中一种进行安装&#xff0c;版本说明&#xff1a; base 版本基于 pytorch/pytorch:2.5.1-cuda11.8-cudnn9-devel&#xff0c;默认 python 版本…...

Redis做分布式锁

&#xff08;一&#xff09;为什么要有分布式锁以及本质 在一个分布式的系统中&#xff0c;会涉及到多个客户端访问同一个公共资源的问题&#xff0c;这时候我们就需要通过锁来做互斥控制&#xff0c;来避免类似于线程安全的问题 因为我们学过的sychronized只能对线程加锁&…...

lambdaQueryWrapper详细解释

LambdaQueryWrapper 是 MyBatis Plus 提供的一个强大的查询条件构建工具&#xff0c;它允许你使用 Lambda 表达式来构建查询条件&#xff0c;从而使代码更加简洁和易读。下面详细介绍 LambdaQueryWrapper 的使用方法及其底层原理。 什么是 LambdaQueryWrapper&#xff1f; La…...

【工控】线扫相机小结 第三篇

海康软件更新 目前使用的是 MVS_STD_4.3.2_240705.exe &#xff0c;最新的已经到4.4了。 一个大的变动 在上一篇中我们提到一个问题&#xff1a; 需要注意的是&#xff0c;我们必须先设置 TriggerSelector 是 “FrameBurstStart” 还是 “LineStart” 再设置TriggerMode 是 …...

golang中的init函数

程序的初始化和执行都起始于 main 包。如果 main 包还导入了其它的包&#xff0c;那么就会在编译时将它们依次 导入。有时一个包会被多个包同时导入&#xff0c;那么它只会被导入一次&#xff08;例如很多包可能都会用到 fmt 包&#xff0c;但 它只会被导入一次&#x…...

理解和选择Vue的组件风格:组合式API与选项式API详解

目录 前言1. Vue 的两种组件风格概述1.1 选项式 API&#xff1a;直观且分块清晰1.2 组合式 API&#xff1a;灵活且逻辑集中 2. 深入理解组合式 API 的特点2.1 响应式变量与函数式编程2.2 逻辑组织更清晰2.3 更好的代码复用 3. 应用场景分析&#xff1a;如何选择 API 风格3.1 适…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...