- 博客(44)
- 收藏
- 关注
原创 Mysql——索引
但是 Hash 表不适合做范围查询,而 B 树要实现范围查询,只能通过树的遍历来完成范围查询,这会涉及多个节点的磁盘 I/O 操作,范围查询效率也不如 B+ 树。B+ 树的非叶子节点不存放实际的记录数据,仅存放索引,因此数据量相同的情况下,相比存储即存索引又存记录的 B 树,B+树的非叶子节点可以存放更多的索引,因此 B+ 树可以比 B 树更“矮胖”,查询底层节点的磁盘 I/O次数会更少。这种平衡机制保证了插入和删除操作的效率都比B树更高,比如删除根节点的时候,不会像 B 树那样会发生复杂的树的变化。
2024-06-05 22:28:51
601
1
原创 最小时间差
首先可以想到,可以计算出任意两个时间之间的差值,然后比较出最小的,不过这种蛮力方法时间复杂度是O(n^2)。而先将时间列表排序,再计算相邻两个时间的差值,就只需要计算n个差值,而排序阶段时间复杂度通常为O(nlogn),所以优化后的时间复杂度为O(nlogn)。不过需要注意的是还需要考虑第一个和最后一个时间点跨越午夜的时间差的大小。并且一天只有1440分钟,如果时间列表大于1440,那么必然有重复的时间点,最小差值即为0。
2024-06-02 20:48:32
203
原创 验证外星语词典
在解决算法题时,哈希表是经常被使用的工具,可以用来记录字符串中字母出现的次数,字符串中字符出现的位置等,这里用到的就是利用哈希表储存字符串中字符出现的的位置。“外星语”的字母表顺序是不一样的,所以为了方便查找单词顺序,可以创建一个哈希表,哈希表的键为字母表的每个字母,而值为字母在字母表中的顺序。由于“外星语”的字母数量也是有限的,也是26个,所以可以用一个数组模拟哈希表。数组下标对应哈希表的键,数组的值对应哈希表的值。
2024-06-02 20:02:21
326
原创 字母异位词分组
这样每个单词的字母对应的数字相乘可以得到一个数字,而因为因子都是质数,所以只有同一组变位数它们的数字才相同,不互为变位词的两个单词一定会映射到不同的数字。不同的字符数组对象会有不同的哈希码,即使它们的内容相同,它们仍然是不同的对象,具有不同的内存地址,所以就导致相同的变位词不会被分组到同一个列表中。运行结果自然也是不正确的。这段代码的输出是类似 [C@1b6d3586 这样的字符串,这里的 [C 表示这是一个字符数组,而 1b6d3586 是该数组对象的哈希码的无符号十六进制表示。
2024-05-25 22:45:12
723
原创 有效的变位词
的方法做:首先判断字符串是否相等、长度是否不一致,如果相等或者长度不一致则直接返回 false,反之则继续判断两个字符串排序后是否相等。我们可以对字符串s和t分别排序,看排序后的字符串是否相等。如果哈希表的键的取值范围是固定的,并且范围不是很大,则可以用数组来模拟哈希表。数组的下标和哈希表的键相对应,而数组的值和哈希表的值相对应。当然可以继续用长度为65536的数组来模拟哈希表,不过不建议,有点浪费内存。英文小写字母只有26个,因此可以用一个数组来模拟哈希表。此时可以使用真正的哈希表Hashmap。
2024-05-24 20:28:58
288
原创 最近最少使用缓存
Hashmap的get和put方法时间复杂度是O(1),但其不能找出最近最少使用的键。而要想表示一种顺序关系,不难想到可以使用链表,将链尾视为最近最少使用的元素,每次访问一个元素,将该元素移到链头。而将元素移到链头之前,应先将节点从原来位置删掉,若仅仅知道待删除节点,是不能知道前驱节点的,故单链表的增删操作复杂度为O (n)。所以我们需使用双向链表。题目:请设计实现一个最近最少使用缓存,要求如下两个操作的时间复杂度都是O(1)。用哈希表的键保存key,哈希表的值保存双向链表的节点。
2024-05-23 22:10:14
436
原创 String.intern()方法有什么作用
String.intern()方法主要用于优化内存使用和提高字符串比较的性能。通过将字符串添加到字符串池中并返回该字符串在池中的引用,intern()方法可以确保相同内容的字符串在内存中只存在一份,从而节省内存,并且使得使用==操作符进行字符串比较变得可行。String.intern() 是一个 native(本地)方法,其作用是将指定的字符串对象的引用保存在字符串常量池中。字符串池是一个存储字符串字面量的固定池,它的主要目的是为了减少内存使用和提高性能。答案是true,false,true。
2024-05-23 20:24:40
426
原创 插入、删除和随机访问都是O(1)的容器
从哈希表中用O(1)时间删除数据比较简单,之间调用remove方法即可,但从数值中用O(1)时间删除数值,不能简单的remove了,因为被删除的数值不一定位于数组的尾部,当数组中间的数值被删除之后,为了保证数组内存的连续性,被删除之后的数字都要向前移动,由此删除的时间复杂度是O(n)了。数组中存放数值,可以实现在O(1) 时间内随机返回数据集中的数值,同时,哈希表需要知道每个数值在数组中的位置,否则删除数组的数值时就要顺序扫描整个数组。所以哈希表中键是数值,而其对应的值是它在数组中的位置。
2024-05-21 22:16:53
241
原创 排序的循环链表
第二种,刚开始链表只有一个节点,那么两个节点的next指针应互相指向对方。插入节点的规则不难理解:先试图在链表中找到相邻的两个节点,如果这两个节点的前一个节点的值比待插入的值小并且后一个节点的值比待插入的值打,那么就将新节点插入这两个节点之间。如果找不到符合条件的节点,即待插入的值大于链表中已有的最大值或小于已有的最小值,那么新的节点将被插入最大的节点和值最小的节点之间。我就是想当然的以为,head指向最小值对应的节点,循环跳出时,next正好指向最小值节点,curr指向最大值节点,此时插入是正好的。
2024-05-20 22:03:40
225
原创 展平多级双向链表
为了确保在遍历当前节点的子节点之后再继续遍历它的下一个节点,我们需要先将next节点压入栈,然后再将child节点压入栈。这样,栈顶先是child节点,待子链表处理完毕后,再处理next节点,确保了正确的遍历顺序。在展平链表时,我们希望先处理一个节点的子链表,再处理它的下一个节点。通过循环不断从栈中弹出节点进行处理,优先将next节点压入栈,然后将child节点压入栈。多级双向链表中,除了指向下一个节点和前一个节点指针之外,它还有一个子链表指针,可能指向单独的双向链表。弹出2,压入3,再压入4。
2024-05-20 21:05:01
408
原创 (保姆级教程傻瓜式操作)树莓派--基于opencv实现人脸识别
本文介绍了如何使用树莓派和OpenCV库进行人脸识别的步骤和代码,包括人脸数据收集、人脸训练和人脸识别。
2024-05-15 23:08:45
1006
1
原创 AttributeError: module ‘cv2.face’ has no attribute ‘LBPHFaceRecognizer_create’
把opencv-python卸载了,然后安装opencv-contrib-python,我选择的是4.5.4.60,测试没问题。
2024-04-17 01:44:49
539
原创 检查链表是否回文
可以使用快慢指针的方式找到链表的中点,其中快指针每次移动两步,慢指针每次移动一步。当快指针到达链表末尾时,慢指针指向的位置即为链表的中点。这段代码中在处理奇数长度的链表时选择保留中间节点,当然你也可以选择舍弃比较中间节点。然后将链表的后半部分反转,比较前半部分和反转后的后半部分,从而判断链表是否为回文链表。根据回文对称的特点,不难想到将链表分成前后两部分,然后将其中一部分反转的方法。
2024-02-11 18:24:39
334
1
原创 重新排列链表
不难注意到目标链表即为将原链表分成前后两段然后将后半段反转再依照某种规则链接得到的。这样我们的任务即可划分为三步:找到原链表的中点,将原链表的右半端反转,将原链表的两端合并。可以通过快慢指针找到中点不过要注意链表长度分别为奇偶情况的处理,反转可以通过迭代或者递归的方法。另一种相较于这个方法没那么优雅的方法是我们可以使用线性表。因为链表不支持下标访问,所以我们无法随机访问链表中任意位置的元素。因此我们可以利用线性表存储该链表,然后利用线性表可以下标访问的特点,直接按顺序访问指定元素,重建该链表即可。
2024-02-06 18:48:30
398
原创 链表中的数字相加
在正常的两个整数加法运算时,我们是从低位开始,然后依次相加更高位的数字,所以不难想到我们需要将链表反转,方便我们从原链表的尾节点开始遍历到头节点。另外还要考虑运算时产生的进位。不能简单认为将两条链表转变为整数后进行运算,然后将结果转变为链表。因为如果链表很长,这可能会导致整数溢出。
2024-02-02 18:25:00
365
原创 将链表反转
反转链表在解决需要从尾节点开始遍历到头节点的地方很实用,是一种常用的解题技巧。在反转时,我们可以考虑从前向后反转和从后向前反转两种方式。
2024-02-02 17:09:04
317
原创 两个链表的第一个重合节点
还是为了解决两链表因长度不同而带来的问题,仔细思考,如果两链表存在重合节点,那么从第一个重合节点开始到链表尾部都是相同的,也就是说长度不同是发生在重合之前。可以先把两个链表的节点分别放入两个辅助栈,接下来比较两个栈的栈顶节点是否相同,如果相同,则把栈顶节点弹出,然后比较下一个栈顶节点,最后一个相同的节点即为所求节点。为了解决这个问题可以先遍历两个链表得到它们的长度,在第二次遍历时,初始化两指针分别指向链头,令较长的链表中的指针先移动若干步,然后两指针以相同速度在链表中移动,直到相遇。
2024-02-01 18:48:38
1724
原创 链表中环的入口节点
如果知道了环中节点的数目为n,那么我们就可以使用前后双指针,让一个指针先走n步,随后让另一个指针从链头出发,两指针以相同速度移动,那么两指针相遇时的位置就是入口节点(因为前指针先走了n步,相当于绕环一圈,所以两指针相遇的位置就是入口节点),当然前指针先走n的整数倍步也是一样的。首先肯定是要证明链表中有环存在,没环自然没有入口节点。而证明有环可以用快慢双指针的思想,即快指针每次走两步,慢指针每次走一步,如果有环,那么两指针一定会相遇,如果没有环,那么快指针直到抵达尾节点都不会和慢指针相遇。
2024-02-01 17:25:19
542
原创 删除倒数第k个节点
题目要求只遍历链表一次,如果没有这个要求我们可以先遍历一遍链表得出链表长度,然后在第2次遍历时找出第n-k个节点(即倒数第k+1个节点),然后将该节点的next指针指向倒数第k-1个节点。由此,我们可以得知该题关键是如何在遍历一次链表的情况下找到这个倒数第k+1个节点。简单来说就是先让第1个指针移动k-1步,然后再如第2个指针指向链头节点,再让两个指针以相同速度一起移动。当第1个指针到达链尾节点时第2个指针正好指向倒数第k个节点。在一个有哨兵节点的链表中,从第2个节点开始才真正保存有意义的信息。
2024-01-31 17:40:23
334
原创 回文子字符串的个数
即如果存在一个长度为m的回文子字符串,再分别向该回文两端延伸一个字符,并判断这两个字符是否相同,如果相同则找到了一个长度为m+2的子字符串。首先遍历字符串中的每个字符,以每个字符为中心,调用方法统计以当前字符为中心的回文子串数量(回文长度为奇数情况),以及以当前字符和下一个字符为中心的回文子串数量(回文长度为偶数情况),并将结果累加到总计数中。另外,回文的长度即可以是奇数也可以是偶数,所以回文的中心即可能是一个字符,也可能是两个字符。
2024-01-30 17:04:24
523
原创 最多删除一个字符得到回文
与有效回文类似,还是从字符串两端开始逐步比较两个字符是否相同,如果相同则继续移动;如果不同则删除一个字符后判断剩余部分是否构成回文。
2024-01-26 17:26:26
337
原创 有效的回文
常用方法就是双指针。使用两个指针从字符串的两端向中间移动,同时比较对应位置的字符,直到两个指针相遇。由于题目忽略非字母和非数字的字符且忽略大小写,所以跳过那些字符,并将字母转换为小写(或大写)进行比较。指针移动总次数最多等于字符串的长度,所以时间复杂度是O(n)。
2024-01-11 21:17:21
526
原创 包含所有字符的最短字符串
首先扫描字符串t,每扫到一个,哈希表中对应值加1。然后扫描字符串s,每扫描一个就检查哈希表中是否包含该字符,没有则忽略不计。所有如果字符串s包含字符串t的所有字符,那么哈希表中的所有的值应该都小于或等于0。某一时刻两指针间子字符串已经包含字符串t的所有字符,因为目标是找出最短符合条件的子字符串,所有移动左指针,然后判断删除最左边的字符后是否仍包含字符串t的所有字符。还是维护一个滑动窗口,某一时刻两指针间子字符串还没包含字符串t的所有字符,则移动右指针添加新的字符,如果还没有则继续移动右指针。
2024-01-05 23:39:19
1041
原创 不含重复字符的最长子字符串
若两指针之间的子字符串无重复字符,那么移动右指针,然后判断新的字符在子字符串中有没有出现,如果还是没有则继续移动右指针;如果包含重复字符则移动左指针,删除最左边的字符,如果还是包含重复字符就继续移动左指针,如果不包含重复字符,则移动右指针添加新字符。因此下面介绍一种避免多次遍历哈希表的解法。要找出不含重复字符的最长子字符串,可以用一个哈希表统计子字符串中字符出现的字数,出现一次即哈希表中对应位置的数值为1,未出现即为0,重复了那么它的值会比1大。下面是另一种思路相似,但实现方式不同的另一种解法。
2024-01-03 23:55:10
535
原创 字符串中的所有变位词
同样的,也可以用两个数组去分别统计,然后比较两个数组是否相同。维护时使用两个指针,指针i从s2.length()索引开始,逐步加入字母(对应位置加1),指针i-s2.length()从0索引开始,逐步删除字母(对应位置减1)。初始化阶段(前n个字符):时间复杂度是O(n),滑动窗口阶段(从第n个字符开始):时间复杂度是O(m - n),因此,整个算法的时间复杂度是 O(n + m - n) = O(m)。的变种,思路都大差不差,一样可以用一个数组来模拟哈希表去统计字母出现的次数,然后与0比较。
2023-12-30 19:17:14
559
1
原创 安卓保存中文数据和查询中文数据结果不正确问题
在Android开发中,特别是涉及到数据库操作时,对于中文查询和保存中文数据可能需要注意字符编码的处理。确保数据库表的字符集和校对规则正确设置,以支持中文字符。常用的字符集包括UTF-8。如果你使用的是JDBC连接数据库,确保在连接数据库时设置了正确的字符编码。
2023-12-28 12:28:34
348
1
原创 Glide加载不出图片与请求浏览器资源时中文转码问题
现在图片显示问题是解决了,但之后我又发现像诸如http://什么什么/Cybertruck.png英文命名的图片可以访问,而http://什么什么/赛博皮卡.png却不能正常显示。首先确保你的图片 URL 地址是正确的,可以通过在浏览器中直接访问这个 URL 来测试。首先在res下的xml文件夹(没有则创建)里新建network_security_config.xml。然后就是重要的内容了,如果你跟我一样是http的url,并且是Android9.0之后的版本。然后确定依赖库没有问题,我的是4.12.0。
2023-12-28 00:10:04
832
1
原创 字符串中的变位词
可以利用双指针思想,在s_2中设置一个固定长度的窗体,长度比s_1的长度大1。首先,先扫描字符串s_1,每扫到一个字符,对应的值加1,同时,扫描第二个字符串s_2中对应位置字符,对应的值减1,然后先做一次判断,如果满足变位词,数组中的所有值应均为0。第一个指针为i-s1.length(),第二个指针为i(两指针之间包含s1.length()+1个字符),两个指针都右移1位,每当增加一个字符时,数组对应位置的值减1,每当删除一个字符时,数组对应位置的值加1,每次更新后都去判断数组中的所有值。
2023-12-26 19:10:03
551
1
原创 二维子矩阵的数字之和
因为原先sums[row2][col2] - sums[row1-1][col2] - sums[row2][col1-1] + sums[row1-1][col1-1]中row1-1和cow-1可能为负数,而这样在计算时,可以通过sums[i+1][j+1]表示从(0,0) 到(i,j)的部分和,即sums[row2 + 1][col2 + 1] - sums[row1][col2 + 1] - sums[row2 + 1][col1] + sums[row1][col1]。
2023-12-24 18:05:30
460
1
原创 安卓开发之关于如何用viewPager实现三种不同效果的轮播图
还是因为课程设计的缘故,想美化一下界面就想着实现一个轮播图。本文展示了三种效果的轮播图供大家交流,话不多说,直接上代码。
2023-12-23 19:22:11
1350
1
原创 左右两边子数组的和相等
还是累加数组求子数组之和的思想,想求第i个数字左边子数组之和,可以由第i个数字的前缀和减去第i个数字的值,想求第i个数字右边子数组之和,可以由数组所有数字之和减去第i个数字的前缀和。
2023-12-19 18:22:16
503
1
原创 关于安卓连接mysql数据库不显示数据的一种调试办法
今天在完成学校安卓大作业时遇到不显示数据的问题。于是开始调试,偶然机会读到这篇文章。点击Logcat,发现gid为空值。,成功找到了问题所在。
2023-12-18 19:11:40
574
1
原创 0和1个数相同的子数组
变个思路若将数组中的0变为-1,那么此题就是求解子数组数字之和为0的最长子数组的长度。若数组中前i个数字之和为m,前j个数字(j>i)之和也为m,那么从第i+1个数字到第j数字的子数组之和为0,长度为j-i。我们可以把前缀和保存到哈希表中,由于题目是要求最长子数组长度,所以哈希表的键是前缀和(累积和),值是当前扫描的数字的下标。该算法时间复杂度和空间复杂度均为O(n),其中n为数组长度。
2023-12-17 18:17:28
170
1
原创 和为k的子数组
其基本思想是将原始数组中的元素累加起来,形成一个新的数组,新数组中的每个元素表示原数组中对应位置及之前所有元素的累加和。首先计算下标0的数字到所有数字的子数组之和,比如下标0到下标0,记作S_0,下标0到下标i,记作S_i,下标0到下标j,记作S_j,则子数组[i, j]的和就是S_j - S_(i-1)。之前都是用双指针求解子数组之和,但该法有个弊端,那就是当数组中除了有正数外还有负数和零时,添加数字就不一定能增加子数组的和,同样的,删除数字也不一定减小子数组的和。,来确定是否存在和为。
2023-12-16 16:54:25
167
原创 乘积小于k的子数组
由于目标是找出数字乘积小于k的子数组的个数,所以当移动right到某一位置时满足子数组的乘积小于k,不必再移动left,因为只要保持right不动,向又移动left所形成的所以子数组的数字乘积就一定小于k,那么一下子就找到了right-left+1个。初始时,两个指针都指向数组第一个元素,当left和right之间的子数组数字之积小于k时,向右移动指针right,当left和right之间的子数组数字之积大于k时,向右移动指针left。差不多,都采用了窗口的思想。时间复杂度为O(n),理由同。
2023-12-14 20:02:17
206
1
原创 和大于或等于k的最短子数组
初始时,两个指针都指向数组第一个元素,当left和right之间的子数组数字之和小于k时,向右移动指针right,直到两个指针之间的子数组数字之和大于k,否则向右移动指针left,直到两个指针之间的子数组数字之和小于k。假设数组长度为n,尽管代码中有两个嵌套的循环,该解法的时间复杂度仍然是O(n),这是因为在这两个循环中,变量left和变量right都是只增加不减少,都是从0增加到n-1,因此总的执行次数是O(n)。
2023-12-12 17:06:58
248
原创 数组中和为0的三个数字
所以这道题我们可以先排序,然后固定一个数i,然后该题就转换为在排序数组中查找和为-i的两个数。排序算法时间复杂度一般为O(nlogn),排序数组中找出和为给定值的方法时间复杂度为O(n),由于要固定数组中每个数字,故查找三元组的时间复杂度为O(n^2),所以总体时间复杂度为O(nlogn)+O(n^2),仍是O(n^2)。输入一个数组,如何找出数组中所有和为0的3个数字的三元组?例如,在数组[-1,0,1,2,-1,-4]中有两个三元组的和为0,它们分别是[-1,0,1]和[-1,-1,2]。
2023-12-09 15:31:38
444
原创 排序数组中的两个数字之和
我们最容易想到的方法是,先扫描到数字i,再依次判断其余数字之和是否等于k,假设数组长度为n,因为每个数字要和其他n-1个数字组合,所以这种解法的时间复杂度是O(n^2)。
2023-12-06 23:33:32
182
1
原创 单词长度的最大乘积
比较大小是不难的,所以这道题的核心是如何判断两个字符串中是否有相同字符,一种暴力解决方案是基于其中一个字符串里的每个字符,扫描判断在另一个字符串中是否存在。假设两个字符串长度分别为p、q,则判断两个字符串是否包含相同的字符的时间复杂度为O(pq)。用哈希表记录字符串中出现的字符判断两个字符串中是否有相同字符,只需判断某个字符是否在对应的哈希表中都出现了。所有字符均为小写字母,所以最多只需在哈希表中查询26次,其为常数,因此可以认为,应用哈希表后判断两字符串是否包含相同的字符的时间复杂度为O(1)。
2023-12-04 22:41:57
196
原创 只出现一次的数字
所以在该题目中,若所有数字第i个数位之和被3整除,说明这个只出现一次的数字第i个数位一定是0。同理,若所有数字第i个数位之和被3除余1,说明这个只出现一次的数字第i个数位一定是1。由此,同类型的题目“输入一个整数数组,数组中只有一个数字出现m次,其他数字都出现n次。假设m不能被n整除”都可以用这种方法:如果数组中所有的数字的第i个数位相加之和能被n整除,那么出现m次的数字的第i个数位一定是0;该题目有个简化的类似题目“输入数组中除一个数字只出现一次之外其他数字都出现两次,请找出那个只出现一次的数字”。
2023-12-03 15:57:44
180
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人