自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(76)
  • 收藏
  • 关注

原创 剑指64——滑动窗口的最大值

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,

2021-01-19 17:05:42 131

原创 剑指65——矩阵中的路径

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。思路:...

2021-01-19 15:46:53 152

原创 剑指66——机器人运动的范围

地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?解:创建一个m行n列得布尔数组,用来访问记录,利用dfs+回溯法class Solution {public: int movingCount(int t

2021-01-18 17:21:20 123

原创 剑指67——剪绳子

给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],…,k[m]。请问k[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。题解分析:当绳子总长度小于等3时,如果在进行剪的话,乘积就会变小所以小于等于三时,最大乘积就是本身,当大于三时,设想长度为4时:最大长度为4,如果剪成两段,长度为2和2就要看长度为2的各自最大乘积,或者剪成1和三

2021-01-15 17:15:02 115

原创 数据结构 基础总结归纳

满二叉树:在一棵二叉树中,如果所有分支节点都有左右子树 而且所有叶子都在同一层上 这样的二叉树就是满二叉树完全二叉树:对于一颗有n个几点的二叉树按层次编号 如果编号为i的节点与同样深度的满二叉树中编号也为i的节点在二叉树中位置完全相同,那这棵二叉树就是完全二叉树(满二叉树一定是完二叉树 完全二叉树不一定是满二叉树)完全二叉树特点:叶子节点只能出现在最下两层最下层叶子节点一定集中在左边连续的位置(层序编号)同样节点数的二叉树,完全二叉树的深度最小前序遍历:二叉树为空 则返回空 否则先访问根节点

2020-12-12 14:41:57 167

原创 c/c++语言基础总结(学习中,不定时更新。。。)

1.编译的过程预处理:特殊符号的处理 生成了.i文件编译:编译器对代码进行语法检查,转成汇编代码.s文件汇编:汇编器将汇编代码转成机器指令生成目标.o文件链接:经过链接器链接生成可执行程序·.exe文件2.关于智能指针主要管在堆上分配的内存,他不是真正意义上的指针,它是将普通的类指针封装成栈对象,当栈对象的生存周期结束就会析构,从而防止内存泄露shared_ptr:通过引用计数的方式来记录当前资源有多少个智能指针引用 要用make_shared或者构造函数传入普通指针3.智能指针是否会内存泄

2020-12-11 10:15:59 184

原创 epoll反应堆模型

epoll 反应堆模型:epoll ET模式 + 非阻塞、轮询 + void *ptr。原来: socket、bind、listen -- epoll_create 创建监听 红黑树 -- 返回 epfd -- epoll_ctl() 向树上添加一个监听fd -- while(1)-- -- epoll_wait 监听 -- 对应监听fd有事件产生 -- 返回 监听满足数组。 -- 判断返回数组元素 -- lfd满足 -- Accept -- cfd 满足 -- read() --- 小-

2020-11-12 11:03:55 250

原创 epoll实现多路io转接

epoll实现多路IO转接思路:lfd = socket(); 监听连接事件lfdbind();listen();int epfd = epoll_create(1024); epfd, 监听红黑树的树根。struct epoll_event tep, ep[1024]; tep, 用来设置单个fd属性, ep 是 epoll_wait() 传出的满足监听事件的数组。tep.events = EPOLLIN; 初始化 lfd的监听属性。tep.data.fd = lfd

2020-11-12 10:58:53 225

原创 利用epoll函数实现服务器

使用epoll(本质是一棵监听红黑树)主要在于记住三个函数的调用,以及相应参数、返回值等int epoll_create(int size); 创建一棵监听红黑树 返回根节点int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); 操作监听红黑树epfd监听红黑树的树根op对红黑树所要进行的操作 : EPOLL_CTL_ADD 添加fd到 监听红黑树 EPOLL_CTL_MOD 修改fd在 监听红黑树上的监听事件

2020-11-10 21:21:44 269

原创 poll函数建立服务器

int poll(struct pollfd *fds, nfds_t nfds, int timeout);fds:监听的文件描述符【数组】 struct pollfd { int fd: 待监听的文件描述符 short events: 待监听的文件描述符对应的监听事件 取值:POLLIN、POLLOUT、POLLERR short revnets: 传入时, 给0。如果满足对应事件的话, 返回 非0 --> POLLIN、POLLOUT、POL

2020-11-10 21:03:20 217

原创 select实现多路io转接

(内核提供函数)int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout); nfds:监听的所有文件描述符中,最大文件描述符+1 readfds: 读 文件描述符监听集合。 传入、传出参数 writefds:写 文件描述符监听集合。 传入、传出参数 NULL exceptfds:异常 文件描述符监听集合 传入、传出参数 NULL timeout:

2020-11-10 16:52:51 233

原创 多线程并发服务器思路建立

1.socket 函数创建套接字 lfd2.bind 绑定地址结构3.listen 设置监听上限while (1) { cfd = Accept(lfd, ); pthread_create(&tid, NULL, tfn, (void *)cfd);//创建子线程 pthread_detach(tid); // pthead_join(tid, void **); 新线程---专用于回收子线程。 }5. 子线程: void *tfn(void *arg)

2020-11-10 16:17:52 222

原创 多进程并发服务器思路建立

1.socket 函数创建套接字 lfd2.bind 绑定地址结构3.listen 设置监听上限4.循环监听客户端连接请求5.子进程关闭lfd(用于监听客户端连接文件描述符)完成指定任务6.父进程关闭cfd(关闭与客户端进行数据通信的文件描述符)注册信号捕捉函数,回收子进程注:如果不进行信号捕捉 子进程回收,就会产生僵尸进程代码实现(实现客户端小写转大写功能)1.#include <stdio.h> 2.#include <ctype.h> 3.#inc

2020-11-10 15:49:30 220

原创 网络编程的一些基础知识

OSI 七层模型:物理 数据链路 网络 传输 会话 表示 应用TCP/IP 4层模型:应用 传输 网络 链路

2020-11-10 15:29:20 148

原创 利用Socket套接字实现一个基本的c/s通信模型

几个主要的函数:服务器端:socket() 产生一个套接字,返回一个新套接字对应的文件描述符(不用于接下来与客户端通信,而是用来监听)bind() 绑定服务器端地址结构listen() 不是监听 是用来设置与服务器端链接上限个数(同时进行三次握手的客户端数量)accept()阻塞等待客户端建立连接,成功返回一个与客户端成功链接的socket文件符客户端:connect() 与服务器建立链接客户端不需要bind绑定地址结构,系统会隐式绑定...

2020-11-03 21:46:06 588

原创 宽度优先遍历(BFS)深度优先遍历(DFS)

BFS:set+queueDFS:stack+set以当前结点距离最近的原则输出,使用set记录,避免重复输出,使用queue进行输出void BFS(Node* node){ if (node == NULL)return; unordered_set<Node*>s; queue<Node*>q; q.push(node); s.insert(node); while (!q.empty()) { Node* tmp = q.front(); cou

2020-06-17 16:17:26 253

原创 拓扑排序

拓扑排序适用于无环图,且图是有向的,而且要有入度为0的结点分析:使用map存储结点和结点的入度信息,使用队列存储入度为0的信息,依次弹出队列中入度为0的结点,并把与之相连的结点入度减1,如果为零就加入到队列中,最后用一个链表记录输出顺序//拓扑排序list<Node*> Sort(Graph graph){ unordered_map<Node*,int>m; queue<Node*>q; unordered_map<int,Node*>::it

2020-06-17 15:36:40 152

原创 图的建立

图的组成元素:顶点边建立顶点类,成员包包括:入度,出度,数值,以此顶点为出发点的边(放入链表中) 当前结点直接相连的下一个结点(放入链表中)class Node{public: int val; int in; int out; list<Node*>next; list<Edge*>edges; Node(int x) :val(x),in(0),out(0){}};边类的构成:边的权值 出发顶点 末尾结点class Edge{publ

2020-06-17 15:00:31 160

原创 左神算法课——并查集c++实现

class UnionFindSet{private: hash_map<char, char>fatnerMap; hash_map<char, int>sizeMap;public: UnionFindSet(vector<char>data); char findHead(char cur);//找代表结点 bool isSame(char a, char b);//是否同集合 void Union(char a, char b);//合并};

2020-06-16 17:24:36 210

原创 岛问题

1.题目:岛问题一个矩阵中只有0和1两种值,每个位置都可以和自己的上、下、左、右四个位置相连,如果有一片1连在一起,这个部分叫做一个岛,求一个矩阵中有多少个岛?举例:0 0 1 0 1 01 1 1 0 1 01 0 0 1 0 00 0 0 0 0 0这个矩阵中有三个岛。思路:建立一个感染函数,先遍历矩阵,如果发现有为一的地方则调用感染函数,递归进行上下左右的搜索,并把周围为相连为1的地方标记为2,知道搜索到不为1或者越界不在进行递归。#define width 6#define h

2020-06-16 16:50:51 150

原创 C++设计RandomPool结构

思想:使用两个map。一个存放string int另一个存放映射 int string 用此来保证等概率删除的时候:用最后的位置来填补删除位之的空缺class Poll{public: Poll() { this->size = 0; } void Map_insert(string); void Map_delete(string); void GetRandom();private: map<string,int>m1; map<int,string&

2020-06-11 18:35:13 114

原创 已知一棵完全二叉树,求其节点的个数。要求:时间复杂度低于O(N),N为这棵树的节点个数

///已知一棵完全二叉树,求其节点的个数//给根据二叉树的性质,二叉树的结点个数=2^k - 1;k为二叉树的高度//遍历当前结点左子树最深处,就是二叉树高度(因为完全二叉树是从左边开始堆砌的)//再遍历当前结点右子树的左子树最深处,判断是否到达了k//如果达到了k,那么右子树也是满二叉树,递归右子树//如果未达到k。那么右子树是高度小于左子树的满二叉树,直接公式class TreeNode{public: int val; TreeNode*left; TreeNode* righ

2020-06-11 16:19:35 408

原创 判断一个树是否为二叉搜索树

判断一个树是否为二叉搜索树二叉搜索树:任何一个结点都比他的左孩子大,比他的右孩子小思路:中序遍历的顺序是左根右如果中序遍历的数值顺序是升序排列的,那就是二叉搜索树 typedef class TreeNode{public: int val; TreeNode* left; TreeNode* right; TreeNode(int x) { this->val = x; right = NULL; left = NULL; } }*Tree;void Mid(Tree h

2020-06-11 15:12:30 209

原创 判断一个树是否为完全二叉树

/判断一个树是否为完全二叉树//思路:当一个只要有一个结点只有右孩子,没有左孩子,直接返回false;//当一个结点不是左右孩子都全的时候://左右都全//有左没右或者左右都没有:当是这种情况的时候,遍历剩下的结点都要是叶节点 typedef class TreeNode{public: int val; TreeNode* left; TreeNode* right; TreeNode(int x) { this->val = x; right = NULL; left =

2020-06-11 15:06:31 158

原创 判断一个二叉树是否平衡

//判断是否为平衡二叉树//思路:设计一个返回类,包括了树的高度,是否平衡//递归的去检查左子树,和右子树返回树高度,平衡否?//最后再检查左右子树的高度差//如果大于1,则不平衡,否则选择左右子树较大一个再+1(自己)返回class TreeNode{public: int val; TreeNode*left; TreeNode* right; TreeNode(int x) { this->val = val; this->left = NULL; th

2020-06-11 09:54:46 119

原创 二叉树的序列化与反序列化

//二叉树的先序序列化,与反序列化class TreeNode { public: int val; TreeNode *parent; TreeNode*left; TreeNode* right; TreeNode(int x) { this->val = x; this->parent = NULL; this->left = NULL; this->right = NULL; } };typedef class TreeNode *Tree

2020-06-11 09:29:19 219

原创 在二叉树中找到一个节点的后继节点、前驱节点

//二叉树找前驱结点:中序遍历中一个结点的上一个,后继结点:中序遍历中一个节点的下一结点//不需要遍历整棵树//方法://1.如果一个结点存在右子树,那么他的后继结点一定是右子树中最左的结点//2.如果没有右子树对于一个节点如果不存在右子树,那么如果当前节点的父节点的左子树是当前节点,//那么其父节点就是当前节点的后继节点。如果不存在,当前节点变为其父节点,继续查找。//原因是把父节点视为中节点,如果中节点是后继节点,必须前一个节点是左子树的最后一个节点。//对于2,4是2的左子树最后的节点,

2020-06-10 20:28:14 389

原创 二叉树的前序、中序、后序遍历(递归版 非递归版)

前序遍历:根 左 右中序遍历:左 根 右后序遍历:左 右 根typedef class TreeNode{public: int val; TreeNode* left; TreeNode* right; TreeNode(int x) { this->val = x; right = NULL; left = NULL; } }*Tree;//前序 递归版void Pre(Tree head){ if (head == NULL) return; cout &

2020-06-10 20:04:09 128

原创 判断两个单链表相交问题

#include<iostream>#include<vector>#include<stack>#include<math.h>using namespace std;typedef struct ListNode{ int val; ListNode * next;}*List;//判断是否有换,如果有环,则返回入环节点List getLoopNode(List head){ List p = head->next; L

2020-06-10 17:43:40 92

原创 单向链表按某值划分成左边小、中间相等、右边大的形式

方法一:开一个数组,放到数组中,然后利用荷兰国旗法排序//单向链表按某值划分成左边小、中间相等、右边大的形式//利用辅助数组void ListSort(List head, int num){ vector<int >v; List p = head; p = p->next; while (p != NULL) { v.push_back(p->val); p = p->next; } int cur = 0; int x = -1; i

2020-06-09 18:34:01 236

原创 判断回文链表

//判断回文链表//1.方法一:利用栈结构,把链表倒进去,然后一一弹出比对//2.方法二:快慢指针//快慢指针+栈 减少了额外空间复杂度bool Istrue(List head){ //假设是含有头节点的 head = head->next; while (head== NULL|| head->next == NULL) return true; List p1 = head->next; List p2 = head; while (p1->nex

2020-06-09 18:23:22 87

原创 打印两个有序链表的公共部分

打印链表的公共部分类似外排方式(外排不了解的请点击查看算法流程3),原理如下:设置两个指针分别指向链表1和链表2的第一个数,比较指针所指的数的大小(1)如果链表1的数字小,则链表1的指针后移,指向后一个数;(2)如果链表2的数字小,则链表2的指针后移,指向后一个数;(3)如果两个数相等就打印输出当前数,并把指针1,2都向后移一位。bool Findnum(int arr[length][length], int num){ int row = 0;//从有右上角第一行开始 int col =

2020-06-09 18:16:52 101

原创 在行列都排序好的矩阵中找数

思路:从右上角第一个数开始找,因为行和列都是排好序的,所以如果要找的数比右上角的数小的话则向左移动,如果比右上角数大的话,则向下移动,然后依次继续比较bool Findnum(int arr[length][length], int num){ int row = 0;//从有右上角第一行开始 int col = length - 1; while (col >= 0 && row <= length - 1) { if (arr[row][col] > n

2020-06-09 18:12:47 238

原创 之字打印矩阵

本题之字形输出矩阵,根据方向可分为左下到右上和从右上到左下两个方向输出,实际上可以看成斜向输出,具体方向作为bool变量更改就可以。考虑设置A,B两个点作为辅助,最开始A、B两点都在左上角位置(0,0)(0,0)位置。(1)AB之间的连线就是需要输出的数字,每轮输出后A向右移,B向下移;(2)使用一个bool变量表示打印的方向,每轮打印过后取逆;(3)当A移到最右端则下移,B移到最下端则右移,直到A移void Rotationmatrix(int arr[][height], int a, int

2020-06-09 16:15:37 154

原创 旋转正方形矩阵

逐层旋转,右由外向内void Rotationmatrix(int arr[][height], int a, int b, int c, int d){ int times = d - b; for (int i = 0; i < times; i++) { int temp = arr[a][b+i]; arr[a][b + i] = arr[c - i][b]; arr[c-i][b] = arr[c][d - i]; arr[c][d - i] = arr[a + i

2020-06-09 15:57:53 105

原创 转圈打印矩阵

利用左上角的点和右下角的点//转圈打印矩阵 肯定是正方形#define height 3#define width 3void print(int arr[][height], int a, int b, int c, int d){ if (a == c) { for (int i = b; i <= d; i++) { cout << arr[a][i]; } } else if (b == d) { for (int i = a; i

2020-06-09 15:48:09 89

原创 使用队列实现栈,使用栈实现队列

使用队列实现栈结构,队列是先进先出,栈是后进先出使用两个栈实现队列:(1)一个队列命名为data,所有数据压入此队列。(2)当需要出栈的操作时,把除队列最后一个元素外的所有元素出队列并压入help队列。(3)此时data还有最后一个元素,是最后进来的元素,pop掉(4)交换data和help的引用(5)若继续碰到出栈操作继续2,3步骤,直至size ==0eg:当前data有1,2,3,4,5分别进入队列,出栈时,把除5外1,2,3,4放入help,最后一个5释放掉,交换data与help,此

2020-06-09 15:43:55 181

原创 返回栈中最小元素

思路:利用两个栈,一个用来放数据,一个用来放最小值,当两个栈都是空的时候,直接都push,当存放最小值栈不是空的时候,需将要压栈数据和当前栈顶元素大小比较,如果比当前栈顶元素小压入,如果比当前栈顶元素大,则继续压入栈顶元素`///返回栈中最小元素//s1正常压栈,s2是辅助栈void add_num(stack<int>&s1, stack<int>&s2, int num){ s1.push(num); if (s2.empty()) { s2.p

2020-06-09 15:36:05 167

原创 使用数组实现队列,使用数组实现栈

使用数组实现栈结构在数组上增加一个index标记,他代表着数组中下一个数该放的位置,从而可以完成进栈,出栈的操作#define length 10void push(int arr[],int a, int &index){ if (index == length) { cout << "栈已满,无法入栈" << endl; } else { arr[index++] = a;//放完元素之后移动index的指向 }}void pop(in

2020-06-09 15:21:44 131

原创 堆排序,另一版本

重新写了一遍堆排序,比上一版本更清晰void heapsort(int a[], int size){ while (size > 1) { swap(a[0], a[size - 1]); size--; heapify(a, 0, size); }}void heapify(int a[], int index, int size)//自顶向下{ int left = index * 2 + 1; while (left < size) { int l

2020-06-09 15:05:39 85

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除