- 博客(180)
- 收藏
- 关注
原创 128. 最长连续序列
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。就是把连续的数字视作在一个联通分量中,并查集中元素的父节点是连续数字中的最大数字。请你设计并实现时间复杂度为 O(n) 的算法解决此问题。这道题竟然可以用并查集,感觉很神奇哈。然后遍历数组,找到长度最长的序列长度。
2023-06-06 21:09:07 144
原创 1202. 交换字符串中的元素
给你一个字符串 s,以及该字符串中的一些「索引对」数组 pairs,其中 pairs[i] = [a, b] 表示字符串中的两个索引(编号从 0 开始)。输入:s = “dcab”, pairs = [[0,3],[1,2],[0,2]]输入:s = “dcab”, pairs = [[0,3],[1,2]]交换 s[1] 和 s[2], s = “bacd”交换 s[0] 和 s[2], s = “acbd”交换 s[1] 和 s[2], s = “abcd”并查集的题目,还是有些难度的。
2023-06-05 23:38:55 419
原创 1319. 连通网络的操作次数
给你这个计算机网络的初始布线 connections,你可以拔开任意两台直连计算机之间的线缆,并用它连接一对未直连的计算机。用以太网线缆将 n 台计算机连接成一个网络,计算机的编号从 0 到 n-1。1.并查集中维护一个变量cnt连通分量数,(如果将并查集视作武林中的各个门派,那么cnt是门派的个数)。在两个节点合并的时候,cnt–。链接:https://leetcode.cn/problems/number-of-operations-to-make-network-connected。
2023-06-05 21:33:41 164
原创 684. 冗余连接
UnionFind是并查集,用哈希表保存元素的父节点,mergeSet函数将两个集合合并,addSet将元素加入集合,find返回元素的父节点同时进行路径压缩。findRedundantConnection函数将每个节点都加入并查集之后,按照入参合并集合。如果两个元素具有相同的父节点,同时还有一条额外的边,那么这条边是多余的,返回即可。并查集简单应用的题目。
2023-06-05 20:36:39 122
原创 字符串转换整数 (atoi)
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。函数 myAtoi(string s) 的算法如下:读入字符串并丢弃无用的前导空格检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。将前面步骤读入的这些数字转换为整数(即,“123” -
2022-05-13 17:41:23 299
原创 寻找两个正序数组的中位数
可以理解为寻找第k个数字。使用二分的思想,将两个数组的第k/2个数字进行比较,一次排除k/2个数字。如果数组长度小于k/2需要取数组剩余长度,如果一个数组已经处理到最后了,那么直接返回另一个数组的给定位置的值即可。getKth中的k可以理解为找第k个数字(从1开始,找第1个,第2个,…,第k个数字)。class Solution {public: double findMedianSortedArrays(vector<int>& nums1, vector<in
2022-05-02 21:13:58 341
原创 剑指 Offer 11. 旋转数组的最小数字
这道题虽然是一个简单题,但是我觉得还是比较有难度的。需要使用二分查找降低时间复杂度。难点1: 使用二分查找时,不断地将mid值与right值比较,而不是与left值比较才行。具体原因是:对于一个旋转数组来说例如[3,4,5,1,2]。当mid值大于left时,需要收缩左边界。而当mid值小于left时,需要收缩左边界。而对于[1,2,3,4,5]这种没有旋转的数组来说,当mid值大于left时(必然发生),应该收缩右边界。此时出现了矛盾,也即,当mid值大于left时,无法判断应该收缩左边界还是
2022-05-01 13:30:36 180
原创 二叉树的后序遍历
需要注意的点:后序遍历与中序遍历的区别是,当访问某个节点是,可以确定其左孩子已经被访问过了,但是右孩子是否被访问过了还无法确定,因此需要使用一个prev变量,记录一下前一个被访问过的节点,如果右孩子是这个已经被访问过的节点,或者右孩子为空时,此时才能访问当前节点。(访问过该节点的含义是,将该节点放入了res数组,对于后序遍历,其必要条件是,该节点的左孩子和右孩子都被访问过了)/** * Definition for a binary tree node. * struct TreeNode { *
2022-04-17 19:23:17 1049
原创 N叉树的前序遍历和后序遍历
N叉树的前序遍历和后序遍历代码非常相似,只需要修改将val放入res数组的位置即可。需要注意的两点:多叉树遍历需要使用一个map来记录,已经遍历到了第几个孩子节点。1.这个map记录的是,哪个节点已经访问到第几个子节点了。unordered_map也可以用地址作为key。2.多叉树遍历的过程中,pop操作是在当前节点的所有子节点访问结束之后才可以pop。class Solution {public: vector<int> postorder(Node* root) {
2022-04-17 19:16:56 1117
原创 Access Path Selection in a Relational Database Management System 论文阅读和翻译
Access Path Selection in a Relational Database Management System一些概念:RSS:存储系统RSI:存储系统接口,返回元组。SARGS(search arguments):这些谓词能够在RSI返回之前就过滤元组。4.Costs for single relation access paths总的代价公式:COST = PAGE FETCHES + W*(RSI CALLS)RSI CALLS是:预测的返回元组数(?这块我有点疑问:
2022-03-22 11:37:37 1089 2
原创 explicit关键字C++
目录何时使用explicit?explicit关键字的作用是什么?对象的两种初始化方式explicit关键字的作用之前一直比较费解explicit的作用,现在记录一下自己目前的理解。何时使用explicit?当构造函数只有一个参数时,才需要使用。explicit关键字的作用是什么?先举个例子:当构造函数有explicit修饰时:不能够使用:编译时会报错:而当构造函数中不写explicit关键字时,就不会编译报错,并且程序能够正常执行。就不贴图了。总结一下explicit关键字作用
2021-08-21 23:14:43 320
原创 学习使用C++——make_shared函数
学习使用C++——make_shared函数make_shared也是在内存中分配空间,构造一个对象,也会调用构造函数。优点: 提高性能,异常安全(暂时没看懂,目前就知道怎么用)我的错误认知的纠正:1.我竟然写出 shared_ptr<A> objA1 = new A(1,2); 这样的语句,等号左右的类型不匹配,等号左边是一个模板类,等号右边是一个指针,显然不能进行这样的初始化语句。2. shared_ptr<A> objA3 = shared_pt
2021-08-18 23:02:46 6321
原创 自己实现一个字符串C++
需要注意的点:自己实现一个String类,需要注意的点:拷贝构造函数和赋值运算符重载要写深拷贝拷贝构造函数和赋值运算符重载的区别是,拷贝构造需要申请空间,但是赋值运算符重载不需要,它需要释放原有的空间,并考虑自赋值赋值运算符重载返回值是引用。构造函数,如果使用空指针构造,则申请一个字节加\0析构函数要释放空间函数的默认参数写在声明中,不用写在定义中(?)判断自赋值:使用对象的地址——this进行判断,而不能使用*this#include<iostream>#include&l
2021-08-18 21:10:35 228
原创 剑指 Offer 14- I. 剪绳子
给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。注意:题目要求应该是必须要剪一刀,这样如果绳长度为2时,结果为1;长度为3时,结果为2解题思路:dp:递推公式为 f(n) = max(f(n-i)*f(i)) 其中i的取值为[1,n/2
2021-06-11 00:01:23 91
原创 剑指 Offer 29. 顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。解题思路:按层打印,每一层分为上,右,下,左四个部分组成。先计算矩阵的层数,矩阵较短的一边除以2向上取整可得。上右下左四个方向打印的思路很容易想,但是实际遇到一些没想到的点。1.横纵坐标弄反了= = left right实际对应的是矩阵的列。2.对于下和左两个方向,i应该递减不是递增 = =3.矩阵下标不能小于0这里要加判断4.在left==right或者top==botom时,可以不用进行下和左的打印,否则,按照我写的代码,会多
2021-06-06 16:51:37 137
原创 剑指 Offer 58 - I. 翻转单词顺序
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。解题思路:使用一个栈,从后向前将字符串每个字符入栈,如果遇到空格(或到了整个字符串的开始位置),则将栈中元素放到一个字符串中,并追加到结果中。class Solution {public: string reverseWords(string s) { int n = s.size
2021-06-02 00:12:04 246
原创 剑指 Offer 44. 数字序列中某一位的数字
数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从下标0开始计数)是5,第13位是1,第19位是4,等等。请写一个函数,求任意第n位对应的数字。我太菜了= =,写这么个小破函数 ,费死劲了。代码写的也不好,先这样哈思路:找规律1-9 9个数 占9位10-99 90个数 占902位100-999 900个数 占903位使用此规律寻找数位上的数字,分三个步骤:1.确定该数位的数字(下面代码中变量:target)是几位数2.确定该数位
2021-06-02 00:08:54 86
原创 C++构造函数的四种传参方式
今天看到书上对对象直接用=赋值调用构造函数,十分不解,浴室百度了一下发现有四种方式可以对构造函数传参,觉得这几种方式只是是写C++语言的人规定的四种形式,都可以编译使用。// classes and uniform initialization#include <iostream>using namespace std; class Circle { double radius; public: Circle(double r) { radius = r; }
2021-05-15 14:37:22 4689
原创 剑指 Offer 41. 数据流中的中位数
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。例如,[2,3,4] 的中位数是 3[2,3] 的中位数是 (2 + 3) / 2 = 2.5设计一个支持以下两种操作的数据结构:void addNum(int num) - 从数据流中添加一个整数到数据结构中。double findMedian() - 返回目前所有元素的中位数。解题思路两个堆使用两个堆,
2021-04-22 14:57:50 260
原创 剑指 Offer 60. n个骰子的点数
题目把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。概率论知识复习样本点随机试验可能出现的结果,这些结果称为样本点。样本空间样本点全体构成样本空间。事件定义为样本点的某个集合,称某事件发生,当且仅当它所包含的某一个样本点出现。(例如投掷2个骰子,其点数和为3即为一个事件,包含两个样本点:(1,2)(2,1),当然,样本点本身也是一个
2021-04-19 23:08:40 153
原创 剑指 Offer 36. 二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。为了让您更好地理解问题,以下面的二叉搜索树为例:我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱
2021-04-19 11:03:20 85
原创 剑指 Offer 48. 最长不含重复字符的子字符串
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。解题思路:1.使用《剑指offer》上的解题思路:2.使用动态规划+哈希表方法。3.更新规则:f(i)代表以第i个字符为结尾字符的最长不重复字符串长度,此为dp数组(但是代码中没有使用O(n)的空间建立一个数组,由于只需要获得最大长度,使用打擂台的方式获取最大值即可。)对于第i个字符,如果该字符未在哈希表中出现过,那么f(i)=f(i-1)+1;如果它在哈希表中出现过,那么分为两种情况:(1)如果它最后一次出现的位置距
2021-04-18 20:58:17 175
原创 176. 第二高的薪水
编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。如果不存在第二高的薪水,那么查询应返回 null。注意点:1.ifnull使用,如果参数1不为null返回参数1,否则返回null。2.distinct记得使用3.降序排列4.limit offset使用5.mysql中的select A;等同于oracle中的select A from dual;select ifnull( (select distinct Salary from Employee
2021-04-12 19:55:56 91
原创 剑指 Offer 61. 扑克牌中的顺子
犯了一个错误:我先把第i个数字放到集合中,然后去集合中找元素,这样的结果是一定可以找到的,所以应该先找后放。解题思路:1.对数组中数字进行排序2.利用集合保证其不能有重复数字,如果有则直接返回失败,但是0可以重复。3.如果2步骤没有返回,说明没有重复数字,那么此时最大与最小数字差小于5即可,此时一定可以连成顺子。class Solution {public: bool isStraight(vector<int>& nums) { //0.排序
2021-04-11 22:26:43 89
原创 175. 组合两个表
表1: Person±------------±--------+| 列名 | 类型 |±------------±--------+| PersonId | int || FirstName | varchar || LastName | varchar |±------------±--------+PersonId 是上表主键表2: Address±------------±--------+| 列名 | 类型
2021-04-11 20:48:17 85
原创 《DBA的思想天空》书摘——第五章 理解REDO日志
5.1 什么是redo日志REDO日志文件是Oracle数据库实例恢复机制中最为关键的组成部分。REDO日志机制的目的就是确保数据库实例或者服务器发生故障时,不会导致数据库崩溃,不会丢失已经提交的数据。oracle为了实现这个目标,将数据库的变化数据记录在REDO日志文件中,而且通过Redo-Writ-Ahead(RWA)机制确保数据库被变更之前,其变更的REDO日志信息必须先写入日志缓冲区,而事务提交之前也必须首先将日志缓冲区中和这个事务相关的REDO信息写入REDO日志文件。(先写日志到缓冲区,再写数
2021-04-08 17:53:47 267
原创 使用flex进行数字和字符辨别
lex文件分三部分:定义段,实现段和main函数段test.l:%{#include<stdio.h>int k=0,j=0;%}%%[0-9]+ {printf("Number: %s %d\n",yytext,yyleng); k++;}[a-zA-Z]+ {printf("Text: %s %d\n",yytext,yyleng); j++;}\n {return 0;} %%//must have yywrapint yywrap(){}int main
2021-03-25 20:11:13 574
原创 22. 括号生成
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。有效的:["((()))","(()())","(())()","()(())","()()()"]无效的:[")()()(",")())((","))(()(","))()((",")))((("]解题思路:backtracking(n,n):将具有n个左括号和n个有括号的有效的全排列字符串加入到Res中递归的退出条件:该放的都放完了递归将问题规模缩小,这种就是放一个左括号之后,我们放左括号的任务就
2021-03-20 16:08:01 73
原创 46. 全排列
解题思路:回溯backtracking函数的作用:将nums数组在使用情况为used数组时,即排除used数组中已经使用过的元素之后,剩下的元素进行全排列,并将这个全排列加入到path中,如果达到数量,则将其加入结果队列中。class Solution { vector<int> path; vector<vector<int>> res;public: vector<vector<int>> permute(vec
2021-03-20 15:13:05 83
原创 141. 环形链表
错误:循环退出点写错了:应该选择每次循环都改变的变量进行判断。循环中判断的条件位置写的不对,应该先让两个指针走两步,然后在判断/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: bo
2021-03-17 22:46:49 67
原创 剑指 Offer 58 - II. 左旋转字符串
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。reverse函数用于反转在[first,last)范围内的顺序(包括first指向的元素,不包括last指向的元素),reverse函数没有返回值解题思路:剑指offer上的三次翻转方式class Solution {public: string reverseLeftWords(stri
2021-03-16 23:22:04 77
原创 剑指 Offer 50. 第一个只出现一次的字符
题目:在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。这个是我自己第二次做写的代码:其中Find的使用也不是自己想起来的,和使用c++11方式的遍历相比,这种方式的遍历代码上感觉好麻烦。1.最开始使用的是map,后来发现没有必要使用有序的结构。2.find 函数使用不够熟练3.循环的方式可以改进解题思路:使用哈希表,如果第一次出现在哈希表中,则将其值置为true,如果不是第一次出现,那么将其值置为false。题目中要求第一个出现,则可以对字符串中的
2021-03-16 23:07:18 107
原创 101. 对称二叉树
判断一棵树是不是对称二叉树解题思路:compare函数的作用是,判断两棵树是否对称。如果一个树的左右子树对称,那么这棵树是一个对称二叉树。判断方式:如果树1的左子树和树2的右子树对称,同时树1的右子树和树2的左子树对称,那么树1和树2对称/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; *
2021-03-12 23:32:42 70
原创 剑指 Offer 27. 二叉树的镜像
解题思路:递归的退出条件:当当前节点为空时退出单层的思路:1.将root的左右子树交换位置2.将左子树的左右子树交换位置3.将右子树的左右子树交换位置/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), righ
2021-03-12 23:02:15 66
原创 剑指 Offer 53 - I. 在排序数组中查找数字 I
统计一个数字在排序数组中出现的次数。解题思路:利用二分查找:(感觉自己能写出二分查找了,嘻嘻)错误点;if(mid+1<n&&nums[mid+1]!=target||mid==n-1){这个或条件没写出来,两种情况可以直接返回:1.如果当前元素的下一个元素的值不等于Target,那么说明当前元素为后边界2.如果当前元素为最后一个元素,那么当前元素为后边界。class Solution {public: int search(vector<int>
2021-03-11 23:58:08 69
原创 剑指 Offer 40. 最小的k个数
输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。解题思路:借助快排partition函数 (这次partiton函数没有写错,嘻嘻)错误点:没有写这一行,如果不写当nk时会溢出,if(nk) return arr;这个地方竟然忘记写pos了,pos = partition(arr,beg,end);class Solution {public: vector<int> getLeas
2021-03-11 23:20:39 73
原创 169. 多数元素
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素。这种方式超时了,但是使用partition函数的思路可以借鉴:由于多数元素一定出现在数组的中间位置,那么使用快排的partition函数能够帮助定位。解题思路:partition函数的作用是:int partition(vector<int>& nums,int beg,int end)对于给定的nums,开始和结
2021-03-10 23:23:01 80
原创 快速排序
错误点:nums[j]>=pivot 这里需要等于号if(i<j) 这个条件判断忘记了class Solution {public: vector<int> sortArray(vector<int>& nums) { int n = nums.size(); if(n==0) return nums; Qsort(nums,0,n-1); return nums; }
2021-03-10 10:40:55 92
原创 归并排序
思路:将数组左边排序,将数组右边排序,然后将有序的左右两边数组合并。错误点:if(beg>=end) return; 这里要写成大于等于,不能是大于,因为当区间内部只有一个元素时,也不许要进行比较了。最后这里将tmp数组重新复制给nums数组时,注意下标,因为tmp数组的索引总是从0开始的,因此这里需要注意。for(int i=0;i<end-beg+1;i++){nums[i+beg] = tmp[i];}class Solution {public: vecto
2021-03-10 10:13:19 74
原创 122. 买卖股票的最佳时机 II
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。解题思路:动态规划,dp[i][0]代表第i天结束后,不持有股票时能够拥有的最大现金数量。dp[i][1]代表第i天结束后,持有股票时能够拥有的最大现金数量。在第0天开始时,不持有股票,现金数量为0.对于dp[i][0]的递推公式:如果第i天结束后不持有股票,有两种可能:(1)第
2021-03-06 11:17:52 98
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人