学习记录
每日任务有两项:做题和总结当天所学知识。做题由简单到困难,刷题顺序是PAT->蓝桥杯->牛客->力扣->PAT···
写博客进行自我监督
day 3✔
力扣练习
力扣算法篇 AC题目:3 无重复字符的最长子串,4 寻找两个正序数组的中位数
3 题目描述:给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
测试用例1:输入:s = "abcabcbb"
输出:3
测试用例2:
输入:s = "bbbbb"
输出:1
测试用例3:
输入:s = "pwwkew"
输出:3
测试用例3:
输入:s = ""
输出:0
此题暴力解法:
直接将所有的字串查找出来,遇到大的记录(这样写的效率十分之低,甚至在力扣上连末尾都算不上)
int lengthOfLongestSubstring(char * s){
int len = strlen(s);
if(len == 0){
return 0;
}else if(len == 1){
return 1;
}else{
int count;
int max = 0;
int flag;
for(int i = 0;i < strlen(s);++i){
for(int j = i + 1;j < strlen(s);++j){
flag = 0;
count = 0;
for(int k = i;k < j;++k){
if(s[j] == s[k]){
flag = 1;
break;
}
count++;
}
if(count + 1 > max){
max = count + 1;
}
if(flag){
break;
}
}
}
return max;
}
}
4 题目描述:
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
测试用例1:输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
测试用例2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
测试用例3:
输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
测试用例4:
输入:nums1 = [], nums2 = [1]
输出:1.00000
测试用例5:
输入:nums1 = [2], nums2 = []
输出:2.00000
此题个人解法:
因为两个数组均为有序且从小到大依次排列,所以我们可以从两个数组的最小的也就是左边开始比较,并且将小的那一个记录下来(这里用mid用来表示用来记录的数),还有要将mid改变的次数记录下来。
从测试用例中我们可以看到一些特殊的情况:
一、当左边数组为空时我们可以知道中位数必定会在右边的数组中,此时又有3种情况:
- 当右边的长度只有1时,则返回右边数组的数即可
- 当右边长度>1且为偶数的时候就需要将右边数组长度一半减1的位置(的数)加上右边数组长度一半的位置(的数)后除去2
- 当右边长度>1且为技术的时候直接返回右边数组长度一半的位置上的数即可。
右边为空时反之。
二、当左边的长度大于右边的长度时,当记录右边数组元素的下标越界的时候要将记录右边元素位置的下标转移到记录当前左边数组下标的后一个,并且按照原来的规则进行比较。不过这时候的区别就是,用于记录位置的两个下标都要后移。当两个数组的长度和为偶数时:函数需要返回的值为当前记录的mid值与 j 所对应的左边的数组元素求和后并除于2。当两个数组的长度和为奇数时:函数返回mid值即可。
tip:并不是左边(右边)比右边(左边)长度大的时候都会产生下标越界
右边长度大于左边长度时类似。
三、当两边数组长度一致时,正常规则比较即可。但是这里有一个点需要注意:就是两边中的其中一边的数组界限把另一边的包含在其中了。例如:左边[1,2] 右边[-1,3]这样如果按照上面的贪心算法继续执行的话会造成i 或者 j的值并不是我们想要的,所以我们还要在函数返回前在确认右边当前位置的数是否大于左边当前当前位置的后一个位置的数。如果大于,那么说明右边的界限将左边包含了进去。
反之亦然。
这里还有一点需要注意的就是如果mid值定义的是整形的话,在函数返回值的时候要做*1.0的处理,这是为了让数据在进行类型转换的时候不产生误差(这里本人反复调试了40分钟。。血的教训啊)。说到这里基本解题思路就讲完了。下面就上代码,有兴趣的可以用手走一遍程序。(值得高兴的事这题除了花的时间有点长外,我的时间复杂度超过了91的人,空间复杂度超过81的人。请容许我得瑟一会,大佬轻喷。。)
代码如下:double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
int mid = 0;
int count = 0;
int flag = 0;
int i,j;
i = j = 0;
if(nums1Size == 0){
if(nums2Size == 1){
return nums2[0];
}else if(nums2Size % 2 == 0){
return (nums2[nums2Size/2]+nums2[nums2Size/2 - 1])* 1.0 / 2;
}else{
return nums2[nums2Size/2];
}
}else if(nums2Size == 0){
if(nums1Size == 1){
return nums1[0];
}else if(nums1Size % 2 == 0){
return (nums1[nums1Size/2]+nums1[nums1Size/2 - 1])* 1.0 / 2;
}else{
return nums1[nums1Size/2];
}
}
while(1){
if(flag == 0){
mid = nums1[i] <= nums2[j] ? nums1[i] : nums2[j];
}else if(flag == 1){
mid = nums2[i] <= nums2[j] ? nums2[i] : nums2[j];
}else{
mid = nums1[i] <= nums1[j] ? nums1[i] : nums1[j];
}
++count;
if((nums1Size + nums2Size) % 2 == 0 && count == (nums1Size + nums2Size) / 2){
if(flag == 0){
if(mid == nums1[i]){
if(i != nums1Size - 1){
if(nums2[j] > nums1[i+1]){
return (mid + nums1[i+1])* 1.0 / 2;
}
}
return (mid + nums2[j])* 1.0 / 2;
}else{
if(j != nums2Size - 1){
if(nums1[i] > nums2[j+1]){
return (mid + nums2[j+1])* 1.0 / 2;
}
}
return (mid + nums1[i])* 1.0 / 2;
}
}else if(flag == 1){
return (mid + nums2[j])* 1.0 / 2;
}else{
return (mid + nums1[j])* 1.0 / 2;
}
}else if((nums1Size + nums2Size) % 2 == 1 && count == (nums1Size + nums2Size) / 2 + 1){
return mid;
}
if(flag == 0){
nums1[i] < nums2[j] ? ++i : ++j;
}else if(flag == 1){
++i;
++j;
}else{
++i;
++j;
}
if(i == nums1Size && flag != 1){
i = j;
++j;
flag = 1;
}else if(j == nums2Size && flag != 2){
j = i+1;
flag = 2;
}
}
}
网络基础知识:
吞吐量相关名词:容量,网络负载,时延容量:两个相连节点的最大带宽
时延有发送时延,传输时延,等待时延,接收时延这四个。
在网络传输中时延抖动应小于时延的1%~2%。
时延抖动可以判断该网络的实时性。
路由选择算法:RIP,OSPF
RIP:最短路径优先,并且16跳后数据包不可达
OSPF:最有接口带宽。
数据在网络中传输时:数据帧越大,误码率越高。(但是现在的网络环境并不是这样)
数据交换有3种:电路交换,报文交换,分组交换。
电路交换:在传输时独占线路。
报文交换:在路由空闲时传输。
分组交换:将一个数据包分为几份再将其发送除去。
关于CTF的学习:
安装kali机与靶机,在kali机上使用netdiscover -r ip/mask的形式来探测网段内的IP。还有当kali忘记root密码之后😅要怎么做。
(参考网址:https://www.cnblogs.com/nuomin/p/5708637.html)
于2021年3月4日00点44分完成博客编写,若发现错误望指正。