话说也坚持写了一个月的小记了。
我的11月也连续每天就提交了力扣,不过好像搞错了,是要搞他的每日一题才能有徽章,我以为是坚持每天写一题也能获得。
亏我还每天都去写,就算没空也搞个简单题,之后就算了吧。
昨天考完试,今天进行不太大强度的学习,下午先是刷题:
今天开头了递归,都是简单题练练手
100. 相同的树
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
bool isSameTree(TreeNode* p, TreeNode* q) {
if(p==nullptr&&q==nullptr)
{
return true;
}
else if((p==nullptr&&q!=nullptr)||(p!=nullptr&&q==nullptr))
{
return false;
}
else if(p->val!=q->val)
{
return false;
}
else
{
return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}
}
226. 翻转二叉树
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
TreeNode* invertTree(TreeNode* root) {
if(root==nullptr)
{
return root;
}
TreeNode *p = root->left;
root->left=root->right;
root->right=p;
invertTree(root->left);
invertTree(root->right);
return root;
}
第二题,稍微有点感觉了,就是本来用swap不行,而且要看一眼root为空的情况。
104. 二叉树的最大深度
给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
int maxDepth(TreeNode* root) {
if(root==nullptr)
{
return 0;
}
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
max左右倒是还记得,但是是直接进行+1,不是用其他的去计数的,明明考研的时候这种应该算是简单的,现在要忘光了。
543. 二叉树的直径
给你一棵二叉树的根节点,返回该树的 直径 。
二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。
两节点之间路径的 长度 由它们之间边数表示。
int diameterOfBinaryTree(TreeNode* root) {
if(root==nullptr)
{
return 0;
}
deepth(root);
//ans=maxDeepth(root->left)+maxDeepth(root->right);//不能直接在根这边找左右子树的深度,因为可能最大直径出现在子树上
return ans-1;//不知道为什么,但是题目的定义就是要-1来着
}
int ans=0;//当前直径为0
int deepth(TreeNode *p)
{
if(p==nullptr)
{
return 0;
}
int l=deepth(p->left);//找左子树的深度
int r=deepth(p->right);//找右子树的深度
ans = max(ans, l+r+1); //当前的左右子树的最大差距,因为每一棵子树都可能出现最大直径
return max(l,r)+1;//这个就是单纯的看左右子树的深度的递归,和前面一题的深度查找差不多
}
// int maxDepth(TreeNode* root) {
// if(root==nullptr)
// {
// return 0;
// }
// return max(maxDepth(root->left),maxDepth(root->right))+1;
// }
不过递归的思路很重要,之前会的,现在都忘了,连简单题上手都感觉难了。
然后去看了随机过程的习题课,看了往年学长讲的一章泊松分布的习题课,讲了7题,做了下确实有不少收获,稍微会做一些了。
然后晚上是看数据库,今天把那个存储过程给看完了,时间充裕,触发器也短,也给看完了,也写了不少笔记和代码:
游标-cursor
游标(CURSOR)是用来存储查询结果集的数据类型,在存储过程和函数中可以使用游标对结果集进行循环的处理。游标的使用包括游标的声明、OPEN、FETCH和 CLOSE,其语法分别如下。
声明游标
DECLARE 游标名称 CURSOR FOR 查询语句;
打开游标:
OPEN 游标名称;
获取游标记录:
FETCH 游标名称 INTO 变量[,变量];
关闭游标:
CLOSE 游标名称;
变量必须在游标之前
create procedure p12(in uage int)
begin
declare u_name varchar(10);#变量必须在游标之前
declare u_status int;
declare u_cursor cursor for select name,age from user where age<=uage;
create table if not exists user2 #建表
(
id int primary key auto_increment,
name varchar(10),
status int
);
open u_cursor;#开启游标
while true do #由于游标会最后有Null,会报错。
fetch u_cursor into u_name,u_status; #游标赋值给变量
insert into user2 values(null,u_name,u_status);#表中插入变量
end while;
close u_cursor;#关闭游标
end;
DECLARE handler action HANDLERFOR condition value l, condition value.... statement;
handler action
条件处理程序-handler
条件处理程序(Handler)可以用来定义在流程控制结构执行过程中遇到问题时相应的处理步骤。
CONTINUE: 继续执行当前程序
EXIT: 终止执行当前程序
condition value
SOLSTATE sqlstate_value:状态码,如 02000
SQLWARNING:所有以01开头的SQLSTATE代码的简写
NOT FOUND:所有以02开头的SOLSTATE代码的简写
SOLEXCEPTION:所有没有被SOLWARNING 或 NOT FOUND捕获的SOLSTATE代码的简写
create procedure p12(in uage int)
begin
declare u_name varchar(10);#变量必须在游标之前
declare u_status int;
declare u_cursor cursor for select name,age from user where age<=uage;
declare exit handler for sqlstate '02000' close u_cursor;
#条件处理
create table if not exists user2 #建表
(
id int primary key auto_increment,
name varchar(10),
status int
);
open u_cursor;#开启游标
while true do
fetch u_cursor into u_name,u_status; #游标赋值给变量
insert into user2 values(null,u_name,u_status);#表中插入变量
end while;
close u_cursor;#关闭游标
end;
存储函数:
存储函数是有返回值的存储过程,存储函数的参数只能是IN类型的。
能够使用存储函数的地方都可以用存储过程替换,还是尽量用存储过程吧。
create function f_1(n int)
returns int deterministic
begin
declare total int default 0;
while n>0 do
set total=total +n;
set n=n-1;
end while;
return total;
end;
select f_1(20);
触发器
触发器是与表有关的数据库对象,指在 insert/update/delete 之前或之后,触发并执行触发器中定义的SQL语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性,日志记录,数据校验等操作。
使用别名 OLD 和 NEW 来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。现在触发器还只支持行级触发,不支持语句级触发。
触发器类型 NEW 和 OLD
insert 型触发器 NEW 表示将要或者已经新增的数据
update 型触发器 OLD 表示修改之前的数据,NEW 表示将要或已经修改后的数据
delete 型触发器 OLD 表示将要或者已经删除的数据
创建存放操作日志的表:
create table user_logs(
id int(11) not null auto_increment,
operation varchar(20) not null comment '操作类型, insert/update/delete',
operate_time datetime not null comment '操作时间',
operate_id int(11) not null comment '操作的ID',
operate_params varchar(500) comment '操作参数',
primary key(`id`)
)engine=innodb default charset=utf8;
触发器-insert类型:
创建:
CREATE TRIGGER trigger name
BEFORE/AFTER INSERT/UPDATE/DELETE
ON tbl name FOR EACH ROW --行级触发器BEGIN
trigger_stmt;
END;
查看:
SHOW TRIGGERS;
删除:
DROP TRIGGER [schema_name.]trigger_name; --如果没有指定 schema name,默认为当前数据库
#插入数据的触发器
create trigger user_insert_trigger
after insert on user for each row
begin
insert into user_logs values #因为是插入的数据,所以用的是new
(null,'insert',now(),new.id,concat('数据内容:',new.name,' ',NEW.age,' ',NEW.status,' ',NEW.gender));
end;
SHOW TRIGGERS ;
drop trigger user_insert_trigger;

触发器-update类型:
create trigger user_update_trigger
after update on user for each row
begin
insert into user_logs values #因为是更新的数据,所以用的是old和new
(null,'update',now(),new.id,concat('更新前数据内容:',OLD.name,' ',old.age,' ',old.status,' ',old.gender,'|更新后数据内容:',new.name,' ',NEW.age,' ',NEW.status,' ',NEW.gender));
end;
show triggers ;
update user set age=24 where age<20;

触发器-delete类型:
create trigger user_delete_trigger
after delete on user for each row
begin
insert into user_logs values #因为是更新的数据,所以用的是old和new
(null,'delete',now(),old.id,concat('删除数据内容:',old.name,' ',old.age,' ',old.status,' ',old.gender));
end;
show triggers ;
delete from user where id=5;

他这边的id=8的数据缺少了一项,他好像就没有记录了。
总的来说,今天一天不错,中午去了肯德基,下午晚上学习,也算干了不少的活。