- 博客(78)
- 收藏
- 关注
原创 项目-- Json-Rpc框架
RPC(Remote Procedure Call,远程过程调用)是一种计算机通信协议,它允许一个计算机程序通过网络调用另一个计算机程序中的子程序(也就是远程过程),并获取返回值。客户端调用远程服务端的方法就像调用本地方法一样,客户端将参数传递给远程方法,远程方法执行后将结果返回给客户端。在这个过程中,RPC抽象了网络通信的复杂性,开发者只需关注于调用函数或方法。这样客户端就可以使用到远程服务器的资源,从而完成一些复杂的计算。
2025-06-07 09:41:20
1239
原创 Git开发
在现实中,当我们完成一个文档的初稿后,后面可能还需要对初稿进行反复修改,从而形成不同版本的文档。显然,经过反复修改,当我们发现前面某个版本的文档才是最符合预期的时候,如果我们是直接在原稿的基础上不停修改,我们是很难直接得到那个最符合预期的版本的,因此我们的做法是:每次修改得到一个新版本后,我们就将该版本保存下来,下次如果需要修改,先将该版本备份再修改。
2025-04-11 01:38:14
1152
原创 算法--递归、搜索与回溯
在[m , n]内本次猜的 i 不同,最后确保获胜所花费的代价就会不同,意味着一定存在一个 i ,无论最后的答案是什么,只要我们这次猜 i ,最后的代价是最小的且确保可以获胜。要想把A中的n个盘子移到C中,只需要先把前n-1个盘子借助C移到B中,再把A中剩余那个盘子移到C中,最后借助A把B中的盘子移到C中。对于任意区间 [m , n] 确保获胜的最小现金数是唯一的,由于我们可能需要多次获取区间 [m , n] 确保获胜的最小现金数,故采用一个二维数组记录它们,需要时直接查询即可。
2025-03-30 17:56:53
753
原创 算法--动态规划
动态规划解决问题的流程为:状态表示一般采用一个表格dp记录问题解决过程中不同的状态,状态表的具体含义需要根据具体问题和经验分析确定确定状态转移方程得到不同状态之间的关系初始化填写已知的状态表部分和处理一些细节部分填写状态表根据状态转移方程填写状态表获取结果根据已经填写的状态表返回结果以上是解决动态规划问题的一般流程,有时候我们可能仅仅只需要特定的几个状态就可以解决问题,此时我们就可以进行一定的空间优化,即用几个变量表示状态,从而将时间复杂度降到O(1)。下面考虑空间优化:面试题 08.01.
2025-03-27 15:18:01
646
原创 算法--贪心
使用一个数组v,下标表示已知的某个子序列的长度,可能存在多个长度相同的子序列,v里面存放该长度的子序列末尾元素中最小的一个数字,假设现在记录了最小长度v[ 1 ]=a,最大长度v[n]=b,现在遍历到nums到c元素时:如果c>b,则v[n+1]=c,否则使用二分查找在v中找到一个元素v[i](0<=i<n),使v[i]<=c且v[i+1]>c,这意味这c一定能插在长度为i末尾元素为v[i]的子序列的后面,令v[i+1]=c。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
2025-03-02 18:34:46
2132
原创 算法15--BFS
解决拓扑排序问题的思路为选择入度为0的顶点将该顶点加入到结果中,同时删除与该顶点相关联的边,重复上面步骤直到没有入度为0的顶点为止(如果此时还有顶点没有选入结果,说明该图不是有向无环图)。你不能进入墙所在的格子,你也不能离开迷宫。岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。以所有值为1的边界点作为起点执行BFS,将离开网格边界的陆地单元格置为0,最后值仍为1的点就是网格中 无法 在任意次数的移动中离开网格边界的陆地单元格。
2025-02-24 23:28:44
924
原创 算法14--优先级队列(堆)
堆主要用于解决排序和topK问题,topK问题还可以使用快速选择算法解决,其时间复杂度为o(n),但空间复杂度较高。注意是排序后的第 k 大元素,不是第 k 个不同的元素。int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。= y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。例如 arr = [2,3] 的中位数是 (2 + 3) / 2 = 2.5。
2025-02-21 00:47:22
769
原创 算法13--队列
我们依旧选择层序遍历二叉树,只不过我们需要为每一个结点按数组存储二叉树一样起一个编号,那么每一层的尾节点编号减去首结点编号加1就是该层的最大宽度。每一层的 宽度 被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。无符号整数就是一个环,不断加1之后又会回到原点,我们算宽度时就相当于算环中两个点的距离,又题目已经保证最终结果不会超过一个int,故尾节点编号减去首结点编号加1得到的就是正确的宽度。给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历。(即从左到右,逐层遍历)。
2025-02-20 00:43:04
568
原创 算法12--栈
给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true。此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。你可以假设给定的表达式总是有效的。给出由小写字母组成的字符串 s,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
2025-02-18 01:20:11
511
原创 算法11--字符串
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。选定一个点作为回文串中心,向两边延申直到不是回文串为止,需要考虑回文串长度为奇数和偶数两种情况。给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。字符串相关的匹配算法有BF算法和KMP算法,自行学习。模拟两数相乘即可,需要注意结果可能存在前导零需要去除。如果不存在公共前缀,返回空字符串 “”。给你一个字符串 s,找到 s 中最长的。直接模拟两数相加即可。
2025-02-09 16:45:00
456
原创 算法10--哈希
给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k。如果我们需要频繁地查找某一个元素,可以考虑使用哈希表,同时考虑到效率,如果可以简单的使用数组模拟哈希表,建议就直接使用数组模拟哈希表,没有必要使用容器。给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。给你一个整数数组 nums。
2025-02-09 15:22:53
558
原创 算法9--链表
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。解法三:与合并两个有序链表类似,只不过我们需要一个堆以获取每条链表的头节点中的最小值。给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。请你将所有链表合并到一个升序链表中,返回合并后的链表。解法一:逐个合并两个链表。
2025-02-06 22:48:52
659
原创 算法8--归并
数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。在股票交易中,如果前一天的股价高于后一天的股价,则可以认为存在一个「交易逆序对」。只需每个元素都绑定好数组下标,再进行归并排序即可,同时为了避免数组的开辟释放,可以提前开好足够的数组空间直接在该数组上操作即可,从而得到一定的优化。,归并排序算法不仅仅是使用该算法对数据进行排序,重要的是在归并的过程中解决某些问题,从而使一些原本时间复杂度较高的问题降到O(n*log2。
2025-02-02 21:30:49
996
原创 算法7--快速排序
给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地 对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。你必须在 不使用任何内置函数 的情况下解决问题,时间复杂度为 O(nlog(n)),并且空间复杂度尽可能小。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。必须在不使用库内置的 sort 函数的情况下解决这个问题。解法二:使用快速排序,时间复杂度可以达到o(n)
2025-01-09 01:34:50
490
原创 算法6--模拟
使用一个哈希表分别记录正在发出声音c、r、o、a、k的青蛙的个数,遍历字符串 croakOfFrogs,如果是字符r、o、a、k之一,如果它的前一个字符的数量为0,说明该字符串不是有效字符,直接返回-1即可,否则前一个字符的数量减1,当前字符的数量加1;例如,要压缩字符串 “3322251” ,我们将 “33” 用 “23” 替换,将 “222” 用 “32” 替换,将 “5” 用 “15” 替换并将 “1” 用 “11” 替换。在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄。
2025-01-08 00:47:53
976
原创 算法5--位运算
假设缺的数字是a和b,先对[1,N]异或得到tmp,再用tmp对数组nums一一异或得到的结果就是a^b,由于a和b是不同的两个数字,那么a^b一定有一个比特位为1,假设a^b的第x个比特位为1,现在[0,N]分为第x个比特位为0和为1的两组数字tmp1和tmp2,再将数组nums也分为第x个比特位为0和为1的两组数字nums1和nums2,此时将tmp1和nums1的数字一一异或即可得到a,将tmp2和nums2的数字一一异或即可得到b。给定一个数组,包含从 1 到 N 所有的整数,但其中缺了两个数字。
2025-01-07 01:47:05
1006
原创 算法4--前缀和
考虑使用一个前缀和和一个哈希表,哈希表记录前缀和为sum的个数,那么map[curSum-k]就是以当前位置为最后一个元素的连续和为k的序列个数。解法二:考虑建立一个前缀和和一个后缀和数组,下标i和前缀和应该是0到i-1的和,不包括当前元素,这样解题就比较方便。考虑使用一个前缀和和一个哈希表,哈希表的键为0-i的和的模k,值为对应模值的个数,需要特别注意负数的取模。给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数。如果数组不存在中心下标,返回 -1。
2025-01-02 16:06:37
673
原创 CSS基础
CSS(Cascading Style Sheets, 层叠样式表 )能够对网页中元素位置的排版进行像素级精确控制,实现美化页面的效果,并能够做到页面的样式和结构分离,简单来说就是CSS用于控制页面的展示效果,而HTML决定页面的结构。
2024-12-07 16:53:36
1109
原创 算法3--二分查找
它的思路很简单,就是将数组分为两部分,一部分是不存在目标的部分,另一部分是目标可能存在的部分,按照这个思路,其实遍历查找也是二分查找,只不过它每次只能排除一个数据,如果是这样的话,那么我们为什么不进行类似于1/4切分或者2/3这种切分,而是以1/2进行切分呢?可以这样想,数据是不确定的,如果进行1/4切分的话,有1/2的概率一次就排除3/4的数据,但也有1/2的概率一次只排除1/4的数据,从整体概率考虑,进行1/2切分是最优的。注意,数组 [a[0], a[1], a[2], …, a[n-2]]。
2024-12-04 23:54:41
1165
原创 算法2--滑动窗口
滑动窗口的本质就是同向双指针,而且两个指针都不回退,条件满足就可以让右指针右移使元素进入窗口,否则右移左指针使一些元素退出滑动窗口直至条件满足,由于左右指针都是只向右移动不回退,故其时间复杂度为O(n),适用于数组等可以下标随机访问的场景。
2024-12-01 22:42:15
728
原创 数据结构--图
图是由顶点集合及顶点间的关系组成的一种数据结构:G = (V, E),其中:顶点集合V = {x|x属于某个数据对象集},是有穷非空集合;E = {(x,y)|x,y属于V} 或者 E = {|x,y属于V && Path(x, y)}是顶点间关系的有穷集合,也叫做边的集合。(x, y)表示x到y的一条双向通路,即(x, y)是无方向的;Path(x, y)表示从x到y的一条单向通路,即Path(x, y)是有方向的。顶点和边:图中结点称为顶点,第i个顶点记作vi。两个顶点vi和vj相关联称作顶
2024-11-27 21:06:34
1084
原创 LRU Cache
为了找到最近最少被使用的数据,我们需要一个双向链表,可以将刚刚被使用的数据头插到链表头部,最近最少被使用的数据就一定是在尾部,从而实现数据插入和删除都是O(1),但是链表查询的效率是O(n),因此我们需要使用一个哈希表(哈希表的增删查改都是O(1)),哈希表的key值是存放数据的关键字,value值是链表中存放该数据的结点的指针。Cache的容量有限,因此当Cache的容量用完后,而又有新的内容需要添加进来时,就需要挑选并舍弃原有的部分内容,从而腾出空间来存放新内容。
2024-11-23 18:47:12
365
原创 数据结构--B树
B树系列包括B树(有些地方写成B-树,注意不要读成B减树,中间的 ‘-’ 是杠的意思,不是减号)、B+树、B树,其中B+树、B树是B树的改进优化,它们最常见的应用就是用于做索引。
2024-11-23 13:46:52
1307
原创 数据结构--跳表
按照上面生成链表的方式,上面每一层链表的节点个数是下面一层的节点个数的一半,这样查找过程就非常类似二分查找,使得查找的时间复杂度可以降低到O(log n)。这样每次插入和删除都不需要考虑其他节点的层数。在查询时,我们不再需要与链表中每个节点逐个进行比较了,只需要先比较上面的一层链表,当目标值小于下一个节点的值时,就跳到下一层继续比较,这样比较的节点数大概只有原来的一半。以此类推,我们可以在第二层新产生的链表上,继续为每相邻的两个节点升高一层,增加一个指针,从而产生第三层链表,这样搜索效率就进一步提高了。
2024-11-20 21:01:45
606
原创 数据结构--并查集
开始时,每个元素自成一个单元素集合,然后按一定的规律将归于同一组元素的集合合并,为了查询效率,应该在合并时让数据量小的集合向数据量大的集合合并(这样就是让数据量小的树的元素高度增加,而数据量大的树的元素的高度不变),同时为了避免某棵树的高度过高,我们还需要进行路径压缩,可以选择在查询某个元素时直接将该元素连接到根节点下面,这样下次查询时速度就很快了。此后我们可能要反复用到查询某一个元素归属于那个集合的运算,适合于描述这类问题的抽象数据类型称为并查集。
2024-11-19 16:10:51
399
原创 VScode调试
编译代码,要确保已经安装gdb,可以使用指令gdb --version 来检查 GDB 是否已安装以及安装的版本,确认安装后在编译时要加上选项:-g,目标文件最好以.out作为后缀。在program字段填入前面生成的.out调式文件的路径,路径这里以绝对路径填入,stopOnEntry字段设为false,然后保存。如果launch.json文件为空,点击右下角的添加配置,然后选择GDB Debug : Launch。调式器选择GDB DEBUG,如果没有就到左边栏目的拓展中下载。点击左边栏目的运行和调式。
2024-11-03 02:10:07
466
原创 MySQL
为了解决上述问题,专家们设计出更加利于管理数据的软件——数据库,它本质就是一套提供数据存取服务的网络程序,可以更有效的管理数据。本文主要讲解MySQL的使用,在熟悉MySQL的使用之后,其他的数据库我们也可以快速上手适应。
2024-11-03 00:05:16
1267
原创 计算机网络(以Linux讲解)
计算机网络网络协议初识协议分层OSI七层模型TCP/IP五层模型--初识网络中的地址管理IP地址MAC地址网络传输基本流程网络编程套接字预备知识网络字节序socket编程UDP socketTCP socket地址转换函数Jsoncpp进程间关系与守护进程进程组会话控制终端作业控制守护进程网络命令TCP/IP五层模型应用层HTTP协议URLHTTP协议格式HTTP的方法HTTP的状态码HTTP的常见HeaderHTTP cookie与HTTP sessionHTTP cookieHTTP sessionHT
2024-10-12 00:50:00
1857
3
原创 Linux线程
该系统调用成功返回0,失败返回错误码,传统的一些函数是,成功返回0,失败返回-1,并且对全局变量errno赋值以指示错误,但pthreads函数出错时不会设置全局变量errno(而大部分其他POSIX函数会这样做),而是将错误代码通过返回值返回,尽管pthreads同样也提供了线程内的errno变量,以支持其它使用errno的代码,对于pthreads函数的错误,建议通过返回值业判定,因为读取返回值要比读取线程内的errno变量的开销更小。通常而言,在读的过程中,往往伴随着查找的操作,中间耗时很长。
2024-08-02 00:26:36
894
原创 算法1--双指针
由于给定一个int型数字,其各位的平方和一定有一个最大值(不会超过int最大值,可以自己验证)和一个最小值0,即数字的各位的平方和得到的数据的个数是有限的,如果我们不停的将数字的各位进行平方和操作,其一定会出现2个相同的数据,即对数据的平方和操作一定是存在循环的,因此可以使用快慢指针解决问题。如果arr[pos1]+arr[pos2]>arr[pos3],那么pos1右边的元素加上arr[pos2]一定大于arr[pos3],此时可以直接计算出当前可以获得的三角形的个数,接着–pos2。
2024-07-22 20:08:00
694
原创 Linux信号
采用第一种方式,父进程阻塞了就不能处理自己的工作了;block位图与pending位图之间互不影响,即使进程没有接收到信号,block位图也可以将该信号对应位置置1阻塞该信号,如果在进程解除某个信号的阻塞之前,该信号多次产生,Linux的处理方法为:对标准信号无论在这期间产生多少次,都只计一次,对实时信号,其会被依次放到一个队列里面。:pending位图位置表示信号的编号,内容表示该信号是否到来,1表示产生了该信号,此时该信号处于未决状态,直到信号递达才会消除该标志(先置0,再递达),0表示未产生该信号。
2024-07-14 23:55:01
1028
原创 Linux进程间通信
数据传输:一个进程需要将他的数据发送给另一个进程资源共享:多个进程之间需要共享某一个资源通知事件:一个进程需要向另一个或一组进程发送消息,通知他们出现了某种情况,如子进程终止需要通知父进程进程控制:一个进程希望完全控制另一个进程的执行(如debug进程),此时就需要控制进程可以拦截另一个进程的所有陷入和异常,并能够及时地知道被控制的进程的状态的改变在内存中有交换数据的空间该空间应该由OS提供,而不能是由通信进程的任何一方提供。
2024-06-21 18:31:03
947
原创 c++类型转换
我们发现&i和p的地址明明是一样的,但值却不一样,这是因为编译器进行了优化认为const变量i既然不能改变,就将i直接放到了寄存器中,我们的p是指向内存中存放的i,在打印i时是到内存中到寄存器取值,而打印*p时是到内存中取值,因此导致了数据不一致的问题。强制类型转换关闭或挂起了正常的类型检查,每次使用强制类型转换前,程序员应该仔细考虑是否还有其他不同的方法达到同一目的,如果非强制类型转换不可,则应限制强制转换值的作用域,以减少发生错误的机会,因此特别建议避免使用强制类型转换。
2024-05-31 21:35:02
615
原创 C++特殊类的设计
由于m_pInstance是一个指针,编译器在释放资源时不会调用Singleton类的析构函数,因此我们需要实现一个垃圾回收类对开辟的资源进行释放:我们定义了一个内部类MyDelete,由该内部类的析构函数对开辟的资源进行释放,利用该内部类定义一个静态成员变量md,当程序退出释放md时调用其析构函数就完成了对资源的释放。在全局中实例化出该对象是因为我们希望该类预先实例化出对象。一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
2024-05-28 15:51:58
866
1
原创 异常与智能指针
我们的想法是:既然是由于A节点里的next或pre指针指向另一个节点B时,调用了share_ptr的赋值拷贝函数后,使得B节点的计数增加了,最后在循环中导致内存无法释放,那我们只需要控制若是next或者pre指针指向节点B时,节点B的引用计数不增加,最后资源不就正常释放了吗,因此我们对pre或者next进行包装另一个类,使其可以正常指向节点,同时在复制拷贝中不增加计数。版本的智能指针,其支持指针的拷贝,原理也较为简单,就是每一份资源都用一个引用计数记录资源的拥有者的个数,只有当引用计数为0时才释放资源。
2024-05-24 12:59:12
1039
原创 C++11
在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字取代了C++98称为C++11之前的最新C++标准名称。不过由于C++03(TC1)主要是对C++98标准中的漏洞进行修复,语言的核心部分则没有改动,因此人们习惯性的把两个标准合并称为C++98/03标准。从C++0x到C++11,C++标准10年磨一剑,第二个真正意义上的标准珊珊来迟。
2024-05-09 18:58:15
989
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人