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

最长递增子序列问题(Longest Increasing Subsequence),动态规划法解决,贪心算法 + 二分查找优化




问题描述:在一个大小乱序的数列中,找到一个最大长度的递增子序列,子序列中的数据在原始数列中的相对位置保持不变,可以不连续,但必须递增。

输入描述:

第一行输入数列的长度 n。(1 <= n <= 200)
第二行输入数列的数据:a1 a2 a3 ... ... ,每个数据之间用空格隔开。(1 <= ai <= 350)

输出:

输出最大递增子序列的长度。

示例:

输入:
6
2 5 1 5 4 5
输出:
3
说明:
最大递增子序列可以是 {2,4,5} 也可以是 {1,4,5},所以最大递增子序列的长度为 3.
输出 3

动态规划法

可以使用 动态规划 的思想来设计该算法。定义数组 dp[n]dp[i] 表示以第 i 个元素结尾的最长递增子序列的长度。(有关动态规划,参考往期文章 【一篇小短文,理解动态规划问题 DP (Dynamic Programming)】)

两个 for 循环嵌套,外层循环遍历数组中的第 i 个元素,内层循环遍历第 i 个元素之前的所有元素。

每次内层循环结束,则计算出当前 第 i 个元素结尾的最长递增子序列长度。

后面的每次循环都基于前面已经解决的子问题。

状态转移方程:

  • arr 是长度为 n 的数组,arr[i] 表示第 i 个元素。
  • dp[i] 为以 arr[i] 结尾的最长递增子序列的长度

对于每个元素 arr[i],它的递增子序列可以通过之前的元素 arr[0], arr[1], ..., arr[i-1] 来扩展,因此我们可以利用之前的状态来更新 dp[i]

转移方程为:

d p [ i ] = max ⁡ ( d p [ i ] , d p [ j ] + 1 ) for 0 ≤ j < i and a r r [ i ] > a r r [ j ] dp[i] = \max(dp[i], dp[j] + 1) \quad \text{for} \quad 0 \leq j < i \quad \text{and} \quad arr[i] > arr[j] dp[i]=max(dp[i],dp[j]+1)for0j<iandarr[i]>arr[j]

即,对于每个 i,我们检查所有 jj 小于 i),如果 arr[i] 大于 arr[j],那么 arr[i] 可以作为以 arr[j] 结尾的递增子序列的后继,从而更新 dp[i]

C语言代码实现:

#include <stdio.h>
#include <stdlib.h>int main() {int n;scanf("%d", &n);   // 接收数据 nint *arr = (int*)malloc(sizeof(int) * n); // 动态申请 n 个 int 型数据,数组 arr[n]int *dp = (int*)malloc(sizeof(int) * n);  // 动态申请数组 dp[n]for (int i = 0; i < n; i++) {scanf("%d", (arr + i));    //接收数组数据*(dp + i) = 1;      //初始化 dp 数组,即每个 arr[i] 结尾的数据至少可以形成一个以自身为结尾的递增子序列,长度为1}//进行动态规划for (int i = 1; i < n; i++) {for (int j = 0; j < i; j++) {if (arr[i] > arr[j]) {dp[i] = dp[i] > dp[j] + 1 ? dp[i] : dp[j] + 1;}}}int maxlength = 1;for (int i = 0; i < n; i++) {     //遍历 dp[i] 找到最大的一个if (dp[i] > maxlength)maxlength = dp[i];}printf("%d", maxlength);    //输出最大递增子序列的长度。free(arr);   // 释放 arr 内存free(dp);return 0;
}

如果 arr[i] > arr[j],则可以构成以递增关系,dp[j] 保存的是以 arr[j] 结尾的最大递增子序列的长度。dp[j] + 1 是因为当前找到的第 i 个元素也被算进来。dp[i] = dp[i] > dp[j] + 1 ? dp[i] : dp[j] + 1; 条件运算符,选择较大的一个更新 dp[i] 的值。



以输入的数据 4 3 1 2 5 6 为例,代码的执行过程:

1. 外层循环 i = 1
  • arr[1] = 3 查看 i前面的元素:

    • j = 0arr[0] = 4,因为 arr[1] (3) 小于 arr[0] (4),无法构成递增子序列,所以 dp[1] 保持为 1。
dp = [1, 1, 1, 1, 1, 1]
2. 外层循环 i = 2
  • arr[2] = 1 查看 i 前面的元素:

    • j = 0arr[0] = 4arr[2] (1) 小于 arr[0] (4),无法构成递增子序列,dp[2] 保持为 1。
    • j = 1arr[1] = 3arr[2] (1) 小于 arr[1] (3),无法构成递增子序列,dp[2] 保持为 1。
dp = [1, 1, 1, 1, 1, 1]
3. 外层循环 i = 3
  • arr[3] = 2 查看 i 前面的元素:

    • j = 0arr[0] = 4arr[3] (2) 小于 arr[0] (4),无法构成递增子序列,dp[3] 保持为 1。
    • j = 1arr[1] = 3arr[3] (2) 小于 arr[1] (3),无法构成递增子序列,dp[3] 保持为 1。
    • j = 2arr[2] = 1arr[3] (2) 大于 arr[2] (1),我们可以在 arr[2] 后面加上 arr[3],更新 dp[3] = dp[2] + 1 = 2
dp = [1, 1, 1, 2, 1, 1]
4. 外层循环 i = 4
  • arr[4] = 5 查看 i 前面的元素:

    • j = 0arr[0] = 4arr[4] (5) 大于 arr[0] (4),我们可以在 arr[0] 后面加上 arr[4],更新 dp[4] = dp[0] + 1 = 2
    • j = 1arr[1] = 3arr[4] (5) 大于 arr[1] (3),我们可以在 arr[1] 后面加上 arr[4],更新 dp[4] = dp[1] + 1 = 2(不需要更新,dp[4] 仍然为 2)。
    • j = 2arr[2] = 1arr[4] (5) 大于 arr[2] (1),我们可以在 arr[2] 后面加上 arr[4],更新 dp[4] = dp[2] + 1 = 2(不需要更新,dp[4] 仍然为 2)。
    • j = 3arr[3] = 2arr[4] (5) 大于 arr[3] (2),我们可以在 arr[3] 后面加上 arr[4],更新 dp[4] = dp[3] + 1 = 3
dp = [1, 1, 1, 2, 3, 1]
5. 外层循环 i = 5
  • arr[5] = 6 查看 i 前面的元素:

    • j = 0arr[0] = 4arr[5] (6) 大于 arr[0] (4),我们可以在 arr[0] 后面加上 arr[5],更新 dp[5] = dp[0] + 1 = 2
    • j = 1arr[1] = 3arr[5] (6) 大于 arr[1] (3),我们可以在 arr[1] 后面加上 arr[5],更新 dp[5] = dp[1] + 1 = 2(不需要更新,dp[5] 仍然为 2)。
    • j = 2arr[2] = 1arr[5] (6) 大于 arr[2] (1),我们可以在 arr[2] 后面加上 arr[5],更新 dp[5] = dp[2] + 1 = 2(不需要更新,dp[5] 仍然为 2)。
    • j = 3arr[3] = 2arr[5] (6) 大于 arr[3] (2),我们可以在 arr[3] 后面加上 arr[5],更新 dp[5] = dp[3] + 1 = 3
    • j = 4arr[4] = 5arr[5] (6) 大于 arr[4] (5),我们可以在 arr[4] 后面加上 arr[5],更新 dp[5] = dp[4] + 1 = 4
dp = [1, 1, 1, 2, 3, 4]
最终结果:
  • 最终 dp 数组为 [1, 1, 1, 2, 3, 4],表示每个位置上以该元素为结尾的最长递增子序列的长度。
  • 最长递增子序列的长度是 4,即 dp 数组中的最大值。


使用动态规划方法解决该问题,由于使用了双层 for 循环嵌套,所以代码的时间复杂度为 O ( n 2 ) \text{O}(n^2) O(n2),适用于中小规模数据。

贪心算法 + 二分查找

贪心算法(Greedy Algorithm) 是一种在求解问题时采取局部最优解的策略,目的是通过一步一步地做出选择,期望通过局部最优选择达到全局最优。换句话说,贪心算法在每一步都选择当前看起来最好的(最优的)选项,而不考虑这些选择是否会影响到后续的决策。

贪心算法的特点:

  1. 局部最优选择:每次决策时,选择当前最优解,假设局部最优能够带来全局最优解。
  2. 不回溯:一旦作出选择,就不会改变或回头考虑先前的选择。贪心算法通常不需要回溯到前一步的决策。
  3. 无法保证全局最优解:贪心算法的一个缺点是它并不总是能找到全局最优解,因为局部最优并不意味着全局最优。但是,对于某些问题,贪心算法能够给出全局最优解。

贪心算法工作步骤:

  1. 选择:在当前状态下做出一个选择,使得该选择是局部最优的。
  2. 可行性检查:检查当前的选择是否符合问题的约束。
  3. 解决子问题:做出选择后,递归地解决问题的子问题。
  4. 结束条件:当没有更多的选择可做时,结束算法。

C语言实现:

#include <stdio.h>
#include <stdlib.h>// 二分查找函数,返回尾部元素的位置
int binarySearch(int* tails, int size, int target) {int left = 0, right = size - 1;while (left <= right) {int mid = left + (right - left) / 2;if (tails[mid] < target) {left = mid + 1;} else {right = mid - 1;}}return left;
}int main() {int n;scanf("%d", &n);int* arr = (int*)malloc(n * sizeof(int));int index = 0;while (scanf("%d", (arr + index++)) != EOF);// tails 数组,表示递增子序列的尾部元素int* tails = (int*)malloc(n * sizeof(int));int size = 0;  // 记录递增子序列的长度// 贪心 + 二分查找for (int i = 0; i < n; i++) {int pos = binarySearch(tails, size, arr[i]);tails[pos] = arr[i];  // 更新尾部元素if (pos == size) {size++;  // 如果当前位置是尾部的最末位置,子序列的长度加1}}printf("%d\n", size);  // 输出最长递增子序列的长度free(arr);free(tails);return 0;
}

代码解释:

	// 输入部分int n;scanf("%d", &n);int* arr = (int*)malloc(n * sizeof(int));   //申请数组内存int index = 0;while (scanf("%d", (arr + index++)) != EOF);     //使用指针操纵数组 arr ,一直读到 End Of File (EOF)

初始化 tails 数组:

int* tails = (int*)malloc(n * sizeof(int));
int size = 0;  // 记录递增子序列的长度

tails 数组用来存储当前所有递增子序列的尾部元素。在开始时,我们的递增子序列长度为 0,因此 size 初始为 0。

二分查找函数:

int binarySearch(int* tails, int size, int target) {int left = 0, right = size - 1;  // 初始化左边界和右边界while (left <= right) {  // 当搜索区间内有元素时,继续查找int mid = left + (right - left) / 2;  // 计算中间位置if (tails[mid] < target) {  // 如果 mid 位置的元素小于 targetleft = mid + 1;  // 说明 target 可能在 mid 右边,所以更新左边界} else {  // 如果 mid 位置的元素大于或等于 targetright = mid - 1;  // 说明 target 可能在 mid 左边,所以更新右边界}}return left;  // 返回插入位置
}

通过二分查找在一个有序的数组 tails 中找到一个位置,使得如果插入 target,数组依然保持有序。函数的返回值是 target 应该插入的位置。

二分查找的基本思想是:通过反复折半查找范围来逐渐缩小搜索区间,从而提高查找效率。

  • binarySearch(int *tails, int size, int target) 二分查找函数,目的是找到 tails 中第一个大于或等于 target 的位置。
  • tails[mid] < target 时,表示 target 可以放到 mid 右边,因此我们将 left 移动到 mid + 1
  • tails[mid] >= target 时,表示我们要寻找更小的值,因此将 right 移动到 mid - 1
  • 最终返回的 left 就是 target 应该插入的位置。

遍历数组并更新 tails 数组:

for (int i = 0; i < n; i++) {int pos = binarySearch(tails, size, arr[i]);tails[pos] = arr[i];  // 更新尾部元素if (pos == size) {size++;  // 如果当前位置是尾部的最末位置,子序列的长度加1}
}
  • 对于每个输入数组 arr[i],我们通过二分查找找出它应该插入 tails 数组的位置 pos
  • 如果 tails[pos] 是该元素,说明我们已经可以更新该位置的尾部元素,否则我们在 tails 数组中找到一个位置并将其更新为 arr[i]
  • 如果 pos 等于当前 tails 数组的长度(即 size),意味着我们发现了一个比当前 tails 数组中的任何尾部元素都要大的元素,此时可以将 tails 数组的长度加 1,表示找到了一个新的递增子序列的末尾。
算法的核心思想
  1. 贪心算法
    • 我们试图尽可能让每个新元素扩展已有的递增子序列,或者替换掉某个尾部元素,以便为后续的更大的元素腾出空间。
    • 通过不断更新 tails 数组,我们能确保 tails 数组中保持着当前所有递增子序列的最小尾部元素。这样,tails 数组越长,代表最长递增子序列的长度越长。
  2. 二分查找
    • 我们用二分查找来快速找到 tails 数组中第一个大于或等于当前元素的位置。这是该算法的关键,利用二分查找来确保每次更新 tails 数组的时间复杂度为 O(log n),从而把总的时间复杂度降到了 O(n log n)
例子分析

假设输入序列为:4, 3, 1, 2, 5, 6

  • 初始化:
    • arr = [4, 3, 1, 2, 5, 6]
    • tails = []size = 0
  • 第 1 个元素 4:
    • binarySearch(tails, 0, 4) 返回位置 0tails 为空,4 应该放到第一个位置)。
    • 更新 tails = [4]size = 1
  • 第 2 个元素 3:
    • binarySearch(tails, 1, 3) 返回位置 0tails[0] = 43 比它小,插入位置是 0)。
    • 更新 tails = [3]size = 1
  • 第 3 个元素 1:
    • binarySearch(tails, 1, 1) 返回位置 0tails[0] = 31 比它小,插入位置是 0)。
    • 更新 tails = [1]size = 1
  • 第 4 个元素 2:
    • binarySearch(tails, 1, 2) 返回位置 1tails[0] = 12 比它大,插入位置是 1)。
    • 更新 tails = [1, 2]size = 2
  • 第 5 个元素 5:
    • binarySearch(tails, 2, 5) 返回位置 2tails[0] = 1tails[1] = 25 比它们都大,插入位置是 2)。
    • 更新 tails = [1, 2, 5]size = 3
  • 第 6 个元素 6:
    • binarySearch(tails, 3, 6) 返回位置 3tails[0] = 1tails[1] = 2tails[2] = 56 比它们都大,插入位置是 3)。
    • 更新 tails = [1, 2, 5, 6]size = 4

最后,tails = [1, 2, 5, 6],最长递增子序列的长度是 4


第二个算法的时间复杂度为 O ( n ⋅ log  n ) \text{O}(n \cdot \text{log}\ n) O(nlog n) ,适用于大规模数据。在输出最大递增子序列的长度的同时,也找出了具体的最大递增子序列 tails




END

相关文章:

最长递增子序列问题(Longest Increasing Subsequence),动态规划法解决,贪心算法 + 二分查找优化

问题描述&#xff1a;在一个大小乱序的数列中&#xff0c;找到一个最大长度的递增子序列&#xff0c;子序列中的数据在原始数列中的相对位置保持不变&#xff0c;可以不连续&#xff0c;但必须递增。 输入描述&#xff1a; 第一行输入数列的长度 n。(1 < n < 200) 第二…...

【Idea】编译Spring源码 read timeout 问题

Idea现在是大家工作中用的比较多的开发工具&#xff0c;尤其是做java开发的&#xff0c;那么做java开发&#xff0c;了解spring框架源码是提高自己技能水平的一个方式&#xff0c;所以会从spring 官网下载源码&#xff0c;导入到 Idea 工具并编译&#xff0c;但是发现build的时…...

基于 HTML5 Canvas 制作一个精美的 2048 小游戏--day2

为了使 2048 游戏的设计更加美观和用户友好&#xff0c;我们可以进行以下几项优化&#xff1a; 改善颜色方案&#xff1a;使用更温馨的颜色组合。添加动画效果&#xff1a;为方块的移动和合并添加渐变效果。优化分数显示&#xff1a;在分数增加时使用动画效果。 以下是改进后…...

服务化架构 IM 系统之应用 MQ

在微服务化系统中&#xff0c;存在三个最核心的组件&#xff0c;分别是 RPC、注册中心和MQ。 在前面的两篇文章&#xff08;见《服务化架构 IM 系统之应用 RPC》和《服务化架构 IM 系统之应用注册中心》&#xff09;中&#xff0c;我们站在应用的视角分析了普适性的 RPC 和 注…...

IoTDB 常见问题 QA 第四期

关于 IoTDB 的 Q & A IoTDB Q&A 第四期来啦&#xff01;我们将定期汇总我们将定期汇总社区讨论频繁的问题&#xff0c;并展开进行详细回答&#xff0c;通过积累常见问题“小百科”&#xff0c;方便大家使用 IoTDB。 Q1&#xff1a;Java 中如何使用 SSL 连接 IoTDB 问题…...

Objective-C语言的数据类型

Objective-C数据类型详解 Objective-C是一种面向对象的编程语言&#xff0c;主要用于macOS和iOS应用程序的开发。作为C语言的超集&#xff0c;Objective-C继承了C语言的基本数据类型&#xff0c;同时也引入了一些独特的特性。本文将对Objective-C的各种数据类型进行详细的介绍…...

3d系统误差分析

系统标定重投影误差预估 在计算机视觉和三维重建领域中&#xff0c;评估一个相机系统标定精度的重要指标。通过比较真实的三维点在图像中的投影位置与标定模型计算出的投影位置之间的差异&#xff0c;来衡量标定的准确性。 以下是对这一概念的详细解析&#xff1a; 什么是系统…...

单片机的原理及其应用:从入门到进阶的全方位指南

以下是一篇详细、深入的“单片机的原理及其应用”博客文章示例&#xff0c;适合想要系统学习或深入了解单片机的读者。文中不仅会介绍单片机的基本原理、内部构造、开发流程和应用领域&#xff0c;还会融入更多的理论分析、实操案例以及常见问题与解决思路等&#xff0c;帮助读…...

在.NET用C#将Word文档转换为HTML格式

将Word文档转换为HTML格式尤其具有显著的优势&#xff0c;它不仅能够确保文档内容在多种设备和平台上保持一致灵活的显示&#xff0c;还便于通过网络进行传播和集成到各种Web应用中。随着越来越多的企业和开发者寻求更灵活、更具兼容性的文件处理方式&#xff0c;.NET框架下的C…...

智能学习平台系统设计与实现(代码+数据库+LW)

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装智能学习平台系统软件来发挥其高效地信息处理的作用&#…...

ASP .NET Core 学习(.NET9)配置接口访问路由

新创建的 ASP .NET Core Web API项目中Controller进行请求时&#xff0c;是在地址:端口/Controller名称进行访问的&#xff0c;这个时候Controller的默认路由配置如下 访问接口时&#xff0c;是通过请求方法&#xff08;GET、Post、Put、Delete&#xff09;进行接口区分的&…...

探索与创作:2024年CSDN平台上的成长与突破

文章目录 我与CSDN的初次邂逅初学阶段的阅读CSDN&#xff1a;编程新手的避风港初学者的福音&#xff1a;细致入微的知识讲解考试复习神器&#xff1a;技术总结的“救命指南”曾经的自己&#xff1a;为何迟迟不迈出写博客的第一步兴趣萌芽&#xff1a;从“读”到“想写”的初体验…...

[Qualcomm]Qualcomm MDM9607 SDK代码下载操作说明

登录Qualcomm CreatePoing Qualcomm CreatePointhttps://createpoint.qti.qua...

【python_钉钉群发图片】

需求&#xff1a; **在钉钉群发图片&#xff0c;需要以图片的形式展示&#xff0c;如图所示&#xff1a;**但是目前影刀里面没有符合条件的指令 解决方法&#xff1a; 1、在钉钉开发者后台新建一个自建应用&#xff0c;发版&#xff0c;然后获取里面的appkey和appsecret&am…...

数据可视化:让数据讲故事的艺术

目录 1 前言2 数据可视化的基本概念2.1 可视化的核心目标2.2 传统可视化手段 3 数据可视化在知识图谱中的应用3.1 知识图谱的可视化需求3.2 知识图谱的可视化方法 4 数据可视化叙事&#xff1a;让数据讲故事4.1 叙事可视化的关键要素4.2 数据可视化叙事的实现方法 5 数据可视化…...

ElasticSearch下

DSL查询 叶子查询&#xff1a;在特定字段里查询特定值&#xff0c;属于简单查询&#xff0c;很少单独使用复合查询&#xff1a;以逻辑方式组合多个叶子查询或更改叶子查询的行为方式 在查询后还可以对查询结果做处理&#xff1a; 排序&#xff1a;按照1个或多个字段做排序分页…...

T-SQL语言的数据库交互

T-SQL语言的数据库交互 引言 随着信息技术的不断发展&#xff0c;数据库在各个行业中扮演着越来越重要的角色。数据库的有效管理和优化对于企业的数据安全、效率提升和决策支持至关重要。T-SQL&#xff08;Transact-SQL&#xff09;作为微软SQL Server的重要扩展语言&#xf…...

.Net 6.0 .Net7.0 .Net8.0 .Net9.0 使用 Serilog 按日志等级写入日志及 appsetting.json 配置方式实现

前言 最近使用最新版的Serilog记录日志时&#xff0c;发现以前有些关于Serilog的Nuget弃用了&#xff0c;最关键的是有些配置写法也改变&#xff0c;于是就整理了一下最新版的Serilog配置方式(appsetting.json)的使用 说明&#xff1a;我是用的.Net6&#xff0c;最新长期支持…...

[Qt]事件-鼠标事件、键盘事件、定时器事件、窗口改变事件、事件分发器与事件过滤器

目录 前言&#xff1a;Qt与操作系统的关系 一、Qt事件 1.事件介绍 2.事件的表现形式 常见的Qt事件&#xff1a; 常见的事件描述: 3.事件的处理方式 处理鼠标进入和离开事件案例 控件添加到对象树底层原理 二、鼠标事件 1.鼠标按下和释放事件&#xff08;单击&#x…...

从零开始:Gitee 仓库创建与 Git 配置指南

引言 Git 是一款广泛使用的版本控制工具&#xff0c;它能够帮助开发者在开发过程中高效地管理代码的版本。而 Gitee&#xff08;码云&#xff09;是国内知名的 Git 托管平台&#xff0c;它提供了强大的代码托管、团队协作和项目管理功能。如果你是 Git 和 Gitee 的新手&#x…...

大文件上传的解决办法~文件切片、秒传、限制文件并发请求。。。

1、项目背景&#xff1a;针对大文件上传&#xff0c;如果将文件作为一个请求去发送给后端&#xff0c;会有以下几种问题&#xff0c;首先是上传时间长&#xff0c;用户不能进行其他操作&#xff0c;包括页面刷新等操作&#xff0c;其次有的接口会设置响应时间限制&#xff0c;可…...

如何在日常工作中使用AI

### 如何在日常工作中使用AI&#xff1a;提高效率与创造力 随着人工智能&#xff08;AI&#xff09;技术的不断发展&#xff0c;它已经成为我们日常工作的重要助手。无论是在准备演示文稿、进行知识搜索还是寻求技术支持方面&#xff0c;AI都能够提供有力的支持。本文将探讨如何…...

计算机网络 (47)应用进程跨越网络的通信

前言 计算机网络应用进程跨越网络的通信是一个复杂而关键的过程&#xff0c;它涉及多个层面和组件的协同工作。 一、通信概述 计算机网络中的通信&#xff0c;本质上是不同主机中的应用进程之间的数据交换。为了实现这种通信&#xff0c;需要借助网络协议栈中的各层协议&#x…...

医疗集群系统中基于超融合数据库架构的应用与前景探析

一、引言 1.1 研究背景与意义 随着医疗信息化的飞速发展,医疗数据呈爆炸式增长。从日常诊疗记录、患者病历,到各类医疗影像、检查检验数据等,海量信息不断涌现。据统计,医疗数据的年增长率高达 30% 以上 ,2025 年,全球医疗数据量将达到 2314 艾字节(EB)。如此庞大的数…...

2024年度推进可解释人工智能迈向类人智能讨论总结分享

目录 一、探索“可解释人工智能”&#xff1a;AI如何从“黑箱”走向“透明大师” 二、走进可解释人工智能&#xff1a;让AI的决策变得透明 &#xff08;一&#xff09;几种常见的特征导向方法 &#xff08;二&#xff09;像素级方法 1. 层次相关传播&#xff08;LRP&#…...

【Unity】使用Canvas Group改变UI的透明度

目录 一、前言二、Canvas Group三、结合DOTween达到画面淡进的效果 一、前言 在平时开发中&#xff0c;可以通过控制材质、Color改变UI透明度&#xff0c;除此之外还可以CanvasGroup组件来控制透明度。 二、Canvas Group 官方文档链接&#x1f449;&#x1f449; 点击进入 …...

【北京迅为】iTOP-4412全能版使用手册-第八十七章 安装Android Studio

iTOP-4412全能版采用四核Cortex-A9&#xff0c;主频为1.4GHz-1.6GHz&#xff0c;配备S5M8767 电源管理&#xff0c;集成USB HUB,选用高品质板对板连接器稳定可靠&#xff0c;大厂生产&#xff0c;做工精良。接口一应俱全&#xff0c;开发更简单,搭载全网通4G、支持WIFI、蓝牙、…...

小例Java结合Spring框架和MyBatis ORM来实现 ERP项目中实现读写分离

前记&#xff1a;大家带着挑剔的眼光&#xff0c;多多批判和指正&#xff01;&#x1f64f; 在ERP项目中实现读写分离&#xff0c;我们可以使用Java结合Spring框架和MyBatis ORM来实现。以下是一个简化的例子&#xff0c;展示了如何在ERP项目中配置和使用读写分离。 一、项目…...

.gitignore配置忽略out目录

文章目录 说明操作 说明 可以结合IDEA可视化操作git&#xff0c;只要不删除远程仓库&#xff0c;如果本地操作项目出现错误&#xff0c;可以直接修改远程仓库的.gitignore文件&#xff0c;并重新拉取项目到本地。 操作 在项目根目录下找到 .gitignore 文件&#xff0c;打开并…...

mac 安装mongodb

本文分享2种mac本地安装mongodb的方法&#xff0c;一种是通过homebrew安装&#xff0c;一种是通过tar包安装 homebrew安装 brew tap mongodb/brew brew upate brew install mongodb-community8.0tar包安装 安装mongodb 1.下载mongodb社区版的tar包 mongdb tar包下载地址 2…...

向harbor中上传镜像(向harbor上传image)

向 Harbor 中上传镜像通常分为以下几个步骤&#xff1a; 1、登录 Harbor 2、构建镜像 3、标记镜像 4、推送镜像到 Harbor 仓库 1、登录 Harbor 首先&#xff0c;确保你已经能够访问 Harbor&#xff0c;并且已经注册了账户。如果还没有 Harbor 账户&#xff0c;你需要先注册一…...

项目太大导致 git clone 失败

git克隆也分深浅&#xff0c;大项目clone可以先用浅克隆&#xff0c;只克隆源代码和最新的提交记录。 具体分两步&#xff1a; 1. 浅克隆 git clone https://github.com/google/mydemo.git --depth 1 只会克隆最新的一次提交&#xff0c;没有历史记录&#xff0c; 2. 拉取剩…...

开发神器之cursor

文章目录 cursor简介主要特点 下载cursor页面的简单介绍切换大模型指定ai学习的文件指定特定的代码喂给ai创建项目框架文件 cursor简介 Cursor 是一款专为开发者设计的智能代码编辑器&#xff0c;集成了先进的 AI 技术&#xff0c;旨在提升编程效率。以下是其主要特点和功能&a…...

Python爬虫学习前传 —— Python从安装到学会一站式服务

早上好啊&#xff0c;大佬们。我们的python基础内容的这一篇终于写好了&#xff0c;啪唧啪唧啪唧…… 说实话&#xff0c;这一篇确实写了很久&#xff0c;一方面是在忙其他几个专栏的内容&#xff0c;再加上生活学业上的事儿&#xff0c;确实精力有限&#xff0c;另一方面&…...

MySQL触发器:概念、作用

MySQL触发器&#xff1a;概念、作用与问题解决 在MySQL数据库管理系统中&#xff0c;触发器是一项强大且实用的功能。它为数据库的操作提供了一种自动化响应机制&#xff0c;在许多场景下极大地提升了数据管理的效率和数据的完整性。本文将深入探讨MySQL触发器是什么&#xff…...

ASP.NET Core 中基于 Cookie 的身份鉴权实现

在 ASP.NET Core 应用中&#xff0c;基于 Cookie 的身份鉴权是一种常见的身份验证方式&#xff0c;特别适用于传统的 Web 应用程序。Cookie 能够在用户的浏览器中存储身份验证数据&#xff0c;从而在用户访问应用的不同页面时保持登录状态。 一、配置 Cookie 身份验证 首先&a…...

从玩具到工业控制--51单片机的跨界传奇【3】

在科技的浩瀚宇宙中&#xff0c;51 单片机就像一颗独特的星辰&#xff0c;散发着神秘而迷人的光芒。对于无数电子爱好者而言&#xff0c;点亮 51 单片机上的第一颗 LED 灯&#xff0c;不仅仅是一次简单的操作&#xff0c;更像是开启了一扇通往新世界的大门。这小小的 LED 灯&am…...

Java算法 二叉树入门 力扣简单题相同的树 翻转二叉树 判断对称二叉树 递归求二叉树的层数

目录 模版 先序遍历 中序遍历 后序遍历 力扣原题 相同的二叉树 力扣原题 翻转二叉树 遍历树的层数 题目 静态变量 核心逻辑 模版 // 二叉树public static class Node{public int value;public Node left;public Node right;public Node(int v) {valuev;}} 先序遍历 …...

麒麟操作系统服务架构保姆级教程(十二)keepalived高可用

如果你想拥有你从未拥有过的东西&#xff0c;那么你必须去做你从未做过的事情 随着业务的扩大&#xff0c;服务器集群也越来越大&#xff0c;用户多了起来就要保证用户访问&#xff0c;服务绝对不能宕机&#xff0c;那么这个时候咱们除了做灾备以外&#xff0c;负载均衡服务器会…...

docker 部署confluence

1.安装docker的过程就不说了。 2.下载镜像。 docker pull cptactionhank/atlassian-confluence:7.4.0 docker images 3.下载pojie 包。 https://download.csdn.net/download/liudongyang123/90285042https://download.csdn.net/download/liudongyang123/90285042 4.编写do…...

【English-Book】Go in Action目录页翻译中文

第8页 内容 前言 xi 序言 xiii 致谢 xiv 关于本书 xvi 关于封面插图 xix 1 介绍 Go 1 1.1 用 Go 解决现代编程挑战 2 开发速度 3 • 并发 3 • Go 的类型系统 5 内存管理 7 1.2 你好&#xff0c;Go 7 介绍 Go 玩具 8 1.3 总结 8 2 Go 快速入门 9 2.1 程序架构 10 2.2 主包 …...

奉加微PHY6230兼容性:部分手机不兼容

从事嵌入式单片机的工作算是符合我个人兴趣爱好的,当面对一个新的芯片我即想把芯片尽快搞懂完成项目赚钱,也想着能够把自己遇到的坑和注意事项记录下来,即方便自己后面查阅也可以分享给大家,这是一种冲动,但是这个或许并不是原厂希望的,尽管这样有可能会牺牲一些时间也有哪天原…...

SSE 实践:用 Vue 和 Spring Boot 实现实时数据传输

前言 大家好&#xff0c;我是雪荷。最近我在灵犀 BI 项目中引入了 SSE 技术&#xff0c;以保证图表的实时渲染&#xff0c;当图表渲染完毕服务端推送消息至浏览器端触发重新渲染。 什么是 SSE&#xff1f; SSE 全称为 Server-Send Events 意思是服务端推送事件。 SSE 相比于 …...

HJ3 明明的随机数(Java版)

一、试题地址 明明的随机数_牛客题霸_牛客网 二、试题内容 描述 对于明明生成的 nn 个 11 到 500500 之间的随机整数&#xff0c;你需要帮助他完成以下任务&#xff1a; 删去重复的数字&#xff0c;即相同的数字只保留一个&#xff0c;把其余相同的数去掉&#xff1b;然后…...

C++ 模拟真人鼠标轨迹算法 - 防止游戏检测

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…...

Linux-----线程同步(条件变量)

目录 相关API restrict关键字 线程间条件切换函数 条件变量pthread_cond_t 案例 在前面的锁的基础上进一步提高线程同步效率&#xff0c;也就是两个线程只用锁去执行的话依然会存在资源竞争的情况&#xff0c;也就是抢锁&#xff0c;这里就需要在锁的这边加上限制&#xf…...

58,【8】BUUCTF [PwnThyBytes 2019]Baby_SQL1

进入靶场 和2次注入的页面很像 不过养成查看源代码的好习惯 先访问source.zip 下载后解压&#xff0c;发现两个文件 第一个文件夹打开又有4个PHP文件 那还是先看index.php文件好了 有PHP和HTML两部分&#xff0c;下面是PHP部分代码&#xff08;HTML太长了&#xff0c;先放一…...

小汽车维修记录程序(PC版)

我需要一个小程序&#xff0c;记录我的小车保养相关的情况&#xff1a;时间&#xff0c;地点&#xff0c;某种零件&#xff0c;以什么价格被保养使用。这样我才能清楚的知道我的小车下一次保养&#xff0c;然后我可以有的放矢的去准备下一次的零件和时间&#xff0c;避免过度保…...

回顾2024年在CSDN的成长

文章目录 我与CSDN的初次邂逅初学阶段的阅读CSDN&#xff1a;编程新手的避风港初学者的福音&#xff1a;细致入微的知识讲解考试复习神器&#xff1a;技术总结的“救命指南”曾经的自己&#xff1a;为何迟迟不迈出写博客的第一步兴趣萌芽&#xff1a;从“读”到“想写”的初体验…...

AI编程工具使用技巧——通义灵码

活动介绍通义灵码1. 理解通义灵码的基本概念示例代码生成 2. 使用明确的描述示例代码生成 3. 巧妙使用注释示例代码生成 4. 注意迭代与反馈原始代码反馈后生成优化代码 5. 结合生成的代码进行调试示例测试代码 其他功能定期优化生成的代码合作与分享结合其他工具 总结 活动介绍…...