数据结构与算法
文章平均质量分 61
数据结构=链表、二叉树、栈、队列、数组、字符串
算法 = 排序、查找、动态规划、贪心、递归、分治、DFS、BFS等等
玛丽莲茼蒿
把热爱的工作做精、做尖才是最酷的
展开
-
深度优先搜索 被围绕的区域 LeetCode
1.被围绕的区域解析:思路是从四个边界出发,找到O后开始深度搜索,和这个O连着的所有O都属于在边界上,先用#标记。四个边界搜索完后,图中剩下的O是真正不挨着边界的O,把他们变成X。最后把#变成O。(1)用DFS求解:注意:①由于LeetCode上给定了图board,行和列都是从0开始的,所以必须进行越界处理class Solution {public: void solve(vector<vector<char>>& board) {原创 2021-03-25 10:08:28 · 617 阅读 · 0 评论 -
深度优先搜索 油田石油块个数
题目描述有@表示石油,@(水平、垂直、对角线)连在一起是一个石油田。求有多少个石油田?注意:(1)根据题目,有8个方向,dir数组需要改(2)回溯的时候不需要标记为0,因为一个点只走一次#include<bits/stdc++.h>using namespace std; char grid[101][101];int vis[101][101];//大括号内含小括号!!! int dir[8][2] = { {-1, -1}, {-1, 0}, {-1, 1}, {0,原创 2021-03-25 10:05:45 · 570 阅读 · 0 评论 -
leetcode-最大子序和-简单
思路:纯暴力解法,i,j,k三层循环。变量i去遍历每一种序列的起始下标。用i和j设置滑动窗口,用k进行滑动窗口内的累加,通过if比较得到最大累加结果,直接放在nums[i]里就行了。最后再对nums这个数组求最大值class Solution {public: int maxSubArray(vector<int>& nums) { for(int i=0;i<nums.size()-1;i++){ int temp..原创 2021-04-28 21:32:42 · 605 阅读 · 0 评论 -
北理、西交计算机夏令营机试题
一、北理1.1 题目描述给定任意个整数,以逗号隔开,输出最后一个重复数字,没有重复数字输出-1输入:1,2,3,4,4,3,2,11,2,3,4,5,6,7,8输出1-1首先得会怎样实现输入,用scanf实现对任意个整数的输入时,只要用非整数作为间隔就行(无论你是逗号,还是空格)# include<bits/stdc++.h>using namespace std;int main(){ int a[100]; int i=0; char y; .原创 2022-04-13 15:19:02 · 455 阅读 · 0 评论 -
棋盘覆盖问题——分治法——代码清晰易懂
一、运行环境DevC++二、题目描述棋盘覆盖问题。有一个2^k × 2^k个方格的棋盘,其中恰有一个方格残缺。用下面四种三格板覆盖更大的棋盘。要求:①两个三格板不能重叠。②三格板不能覆盖残缺方格,但必须覆盖其他所有的方格。用以下形式进行结果输出三、问题分析采用分治的方法解决该问题。把2k×2k的棋盘分为4个2k-1×2k-1的子棋盘,使问题规模变小,直至将棋盘分割为1×1的子棋盘。该问题属于二分法不相似的情况:分割后的4个子棋盘只有一个带有残缺。分治的技巧在于如何划分棋盘,使划分后的原创 2021-05-19 20:39:58 · 5966 阅读 · 4 评论 -
广度优先搜索 迷宫问题
(1)广度优先特点在于,从一个点出发层层扩散出去。所以一打眼看到墨水染色这个题的时候就应该想到用BFS。要实现这个层层扩散就要借用队列先进先出的思想。所以BFS一般都用队列来实现。(2)有模板哦!1.题目描述输入样例:3 3S*#**##*E输出样例:4模板如下:# include<bits/stdc++.h>using namespace std;const int maxn=100+5; //我也不知道为什么要+5 char mpt[maxn][maxn原创 2021-03-25 10:06:38 · 707 阅读 · 0 评论 -
图论--并查集
一、 可套用的样题输入样例4 32 34 33 3输出样例1再看两个例子。思路就是把已经联通的所有点看成一个点(集合),假如一共有N个这样的点(集合),那么还需要N-1条边(左图需要1条,右图需要2条)所有联通的点生成一颗子树,子树的根作为他们的祖宗。也就是说,输入给出了两个点x,y(一条边),我们写一个找祖宗的函数find(x),如果两个点的祖宗相同,那么他俩就是联通的。如果两个点的祖宗不同,那么我们就得让他俩连到一起。形象化的方法是将左边(或右边)作为子树连接到右边(原创 2021-03-25 10:01:46 · 498 阅读 · 0 评论 -
动态规划 背包问题
01背包问题首先,这是一个二维的递推,理解起来可能有些困难。但是背过就行!有的题目中是这样描述的:背包有给定的最大体积,物品有给定的体积和重量。求使得背包重量最大。有的题目中是这样描述的:背包有给定的最大重量,物品有给定的重量和价值。求使得背包价值最大。思路:(1)定义子问题:dp[i][j]表示放入第i个包时,背包体积最大为j时的最大重量(2)子问题的递推关系:当前物品的体积小于等于整个包的体积时,我可以选择把物品放进去,也可以选择不放,当然哪个更有利(使重量最大选哪个);当前物品的体积大原创 2021-03-25 10:11:35 · 652 阅读 · 0 评论 -
二叉树的所有路径和——中等难度
一、题目描述二、问题分析要找从根节点到叶子结点的路径,必须得是先序遍历(1)首先想到用一个全局变量sum去记录每一条路径的累加和(2)叶子结点肯定是递归的一个出口(3)别忘了root==nullpt也是递归的出口,并且要放在函数的第一行三、初版代码/** * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */class Solution {public原创 2021-05-22 11:11:16 · 652 阅读 · 0 评论 -
广度优先搜索 墨水染色
输入一个m*n的矩阵,矩阵中的元素包含0、1、2(其中0表示什么都没有,1表示白纸,2表示墨水),每秒墨水会向四周(上下左右)进行染色,被染色的纸也会对周围的纸进行染色。试问,对于输入的矩阵,多久才能完全染色?如果最终不能完全染色,输出-1.解析:自己手动进行染色,并模拟队列,会发现如果完全染色,队列左后一个元素所带的时间step就是总用时# include<bits/stdc++.h>using namespace std;/*不用标记走没走过,因为染过了的就是2*/char gri原创 2021-03-25 10:07:21 · 724 阅读 · 0 评论 -
深度优先搜索 迷宫问题
1.题目描述:输入样例:3 3S*#**##*E输出样例:4问题解决(下面的代码可看做模板):套模板时要注意改动的地方:(1)寻找路径的时候,一个点被践踏多次,所以回溯的时候要把这个点标记为0(没走过)(2)根据题目,有上、下、左、右四个方向主函数int main{ans=99999999是为了第一次min的时候,让ans=step注意:(1)mpt和vis都需要初始化成0,mpt初始化为0的目的是,待会赋值完后图以外的地方都为0,就形成了一个边界(2)输入图时原创 2021-03-25 10:04:23 · 567 阅读 · 0 评论 -
八皇后问题--递归加回溯
一、问题描述在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。二、问题分析由于皇后们是不能放在同一行的, 所以可以去掉“行”这个因素,即第1次考虑把皇后放在第1行的某个位置, 第2次放的时候就不用去放在第一行了。第2次考虑把皇后放在第2行的某个位置,第3次考虑把皇后放在第3行的某个位置,这样依次去递归。每计算1行,递归一次,每次递归里面考虑8列,即对每一行皇后有8个可能的位置可以放。找到一个与前面行的皇后都不会互相攻击的位置, 然原创 2021-05-07 09:34:03 · 988 阅读 · 1 评论 -
动态规划 最长公共子序列
最长公共子序列注意:(1)定义子问题:dp[i][j]字符串A的前i个和字符串B的前j个拥有的最长公共子序列的长度(2)子问题的递推关系:(3)边界当其中一个子序列为空时,公共子序列个数为0。所以dp的边界如下图所示字符串a/字符串bABBDA000000B0D0C0A0本次代码中对边界的赋值也比较巧妙,直接memset(dp,0,sizeof(dp))4.1 如果单纯求原创 2021-03-25 10:12:09 · 645 阅读 · 0 评论 -
动态规划 最长上升子序列
最长上升子序列首先区分最长上升子序列(左)和最长不下降子序列(右)。思路:(1)定义子问题:dp[i]表示以第i个数结尾的最长上升子序列的个数(2)边界:dp[1]=1(3)子问题的递推关系:比如说当前子序列是5 2 3 7 4 6,我要求dp[6]。我地去6前面找比6小的数,看他们谁的dp[j]+1最大,这个最大值就是dp[6]注意:这个题不是dp[n]就是最终答案(这和子问题的定义有关)。需要用ans一直记录当前情况下的最长上升子序列个数。最终答案是ans。如果你不用ans记录的话,原创 2021-03-25 10:12:40 · 697 阅读 · 0 评论 -
LeetCode【55.跳跃游戏(中等)】贪心算法/动态规划
1. 法一 贪心算法为什么是贪心算法?每遍历一个数,都去考虑当前所能到达的最远下标。class Solution {public: bool canJump(vector<int>& nums) { int far=0;//最大的应该是被不断更新的 for(int i=0;i<nums.size();i++){ if(i>far) //当前所能到达的最远距离到不了i了 ..原创 2022-05-16 17:07:04 · 303 阅读 · 0 评论 -
【数据结构】—— 链表类问题
链表原创 2022-06-17 16:17:07 · 840 阅读 · 0 评论 -
【数据结构】—— 字符串类问题
字符串类算法题解法原创 2022-06-16 10:55:57 · 113 阅读 · 0 评论 -
【Matlab】模拟退火+最低水平线解决物流上的二维装箱问题
这里的装箱问题和我们在算法上归纳的装箱问题不是一个概念!也就是不同于下面这篇博客里的装箱问题。【C++】2018华为软挑:模拟退火+贪心FF解决装箱问题_玛丽莲茼蒿的博客-CSDN博客本文的主要工作是补充这篇博客的缺失代码,使之能够运行。2018华为软挑--模拟退火+FF解决装箱问题【C++代码】_小马哥MAX的博客-CSDN博客算法简介:装箱问题是一个NP完全问题,求解全局最优解有很多种方法:遗传算法、禁忌搜索算法、蚁群算法、模拟退火算法等等,本次使用模拟退火,它的优点是在参数合适的情...原创 2022-04-16 10:55:29 · 3397 阅读 · 10 评论 -
【C++】2018华为软挑:模拟退火+贪心FF解决装箱问题
本文的主要工作是补充这篇博客的缺失代码,使之能够运行。2018华为软挑--模拟退火+FF解决装箱问题【C++代码】_小马哥MAX的博客-CSDN博客算法简介:装箱问题是一个NP完全问题,求解全局最优解有很多种方法:遗传算法、禁忌搜索算法、蚁群算法、模拟退火算法等等,本次使用模拟退火,它的优点是在参数合适的情况下基本上可以100%得到全局最优解,缺点是相较于其他算法,其稳定速度较慢。如果你对退火的物理意义还是晕晕的,没关系我们还有更为简单的理解方式。想象一下如果我们现在有下...原创 2022-04-16 10:30:31 · 2710 阅读 · 0 评论 -
最近公共祖先结点——中等难度
一、题目描述二、问题分析看到二叉树的题一般就用递归求解。还是以根节点的视角来看,(1)如果根节点的左分支有o1或o2,右分支有o2或o1,那么最近共同祖先结点就是根节点,return 根节点的值(2)如果根节点的左分支有o1和o2,右分支什么都没有,那么最近共同祖先结点根节点在根节点的左分支,return 左分支return回来的值(3)如果根节点的右分支有o1和o2,左分支什么都没有,那么最近共同祖先结点根节点在根节点的右分支,return 右分支return回来的值(4)如果左分支和右分原创 2021-05-22 10:16:40 · 713 阅读 · 0 评论 -
数组全部赋值为0
一、通用方法利用string.h封装好的函数#include <cstring>int sum[100];memset(sum,0,sizeof(sum));二、数组为全局变量声明后自动赋值为0,不需要自己赋值int sum[100];int main(){}三、数组为局部变量int main(){ int sum[100]={0};}只能把全部元素赋值为0,不能赋值为其他的数。比如int sun[100]={1}则只是把sum[0]赋值为1...原创 2021-05-07 07:59:54 · 35154 阅读 · 2 评论 -
n个数的r组合
一、题目描述找出n个自然数(1,2,3…n)中r个数的组合。规定:n个数的r组合,其中每r个数中,数不能相同;任何两组组合的数,所包含的数也不应相同。例如5、4、3与3、4、5是同一个组合。为此,约定前一个数应该小于后一个数。二、问题分析自顶向下分析,假如n=5,r=3。第一层,先从大数开始取直到3:5、4、3。第二层,从5开始,自高向低取直到2则有4、3、2。对于4,自高向低取到2则有3、2;对于3也同样,取2。第三层,从4开始,方法不变。最终结果如下图所示:三、抽象成数学模型对于第一原创 2021-05-04 19:46:02 · 1791 阅读 · 0 评论 -
单链表实现多项式相加
一、题目依次输入两个多项式的项数,然后输入每一项的系数和指数,用空格隔开。结果给出两个多项式相加的系数和指数。二、解析思路:(1)结构体包括三部分,系数、指数和next指针(2)写一个创建单链表的函数,先询问用户多项式的项数,然后从首元结点开始依次存储每一项的系数和指数(3)我用链表a去存储结果。两链表a,b比较时,需要三个指针。anow指向链表a当前需要比较的结点,bnow指向链表b当前需要比较的结点,因为后面的分析中需要用到前插法将结点插入a中,所以还需要anow的前驱结点apre。(4原创 2021-04-30 09:49:33 · 3479 阅读 · 1 评论 -
2020蓝桥杯G题:回文日期
2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2日。因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8 位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。有人表示 20200202 是 “千年一遇” 的特殊日子。对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即 2021 年 12 月 2 日。也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA型的回文日期。对此小明也不认.原创 2021-04-16 18:16:29 · 1889 阅读 · 0 评论 -
最大公约数和最小公倍数(辗转相除法)
最大公约数:用辗转相除法求得最小公倍数:给定两个数m和n,他们的最小公倍数=m*n/最大公约数#include<bits/stdc++.h>using namespace std;int main(){ int m,n; //m存放二者之间的大数,n存放二者之间的小数 cin>>m>>n; int p=m*n; if(m<n){ swap(m,n); } /*---辗转相除法----*/ while(n!=0){ int temp原创 2021-04-16 16:04:15 · 872 阅读 · 0 评论 -
vector的基本函数及用法
#include<bits/stdc++.h>using namespace std;vector<int> prices={7,1,5,3,6,4,22}; //声明 int main(){ prices.pop_back(); //弹出 prices.push_back(21); //压入 sort(prices.begin(),prices.end()); //排序 for(int i=0;i<prices.size();i++){ co原创 2021-04-15 14:47:31 · 832 阅读 · 0 评论 -
查找算法 哈希map的使用
1.查找类问题我们首先会想到,顺序查找,复杂度为O(n),但是如果让你查找m数十万次,复杂度变为O(mn)可能会突破时间限制。比如说这个题#include<bits/stdc++.h>using namespace std;int main(){ int mark[200001]={0}; //这样全赋值成0了? int a,b; while(1){ scanf("%d%d",&a,&b); if(a+b==0) break; for(int i原创 2021-04-11 12:06:25 · 1089 阅读 · 0 评论 -
同余模定理在算法中的应用
一、同余模定理a,b两个数对n取余,余数相同则a和b同余。如1 mod 5 = 1,6 mod 5=1;则1和6模5同余二、应用——消除爆int的问题题目:求解(2^0 + 2^1 + 2^2 +…+ 2^n)%2333当n足够大时,超出了int的范围。#include<bits/stdc++.h>using namespace std;int main(){ int ans=0; int n=1000; for(int i=0;i<=n;i++){ in原创 2021-04-08 20:31:05 · 1412 阅读 · 0 评论 -
机试(蓝桥杯)入门级教程
一、都要干什么呢1.常用排序算法2.只需要学递归、分治、贪心、动态规划3.可以学一下STL库函数4.编程题可以只写输入输出语句,与样例即可(因为第一个测试数据一般就是样例)二、题目题目描述1.假设你有一个数组,其中第\ i i 个元素是股票在第\ i i 天的价格。你有一次买入和卖出的机会。(只有买入了股票以后才能卖出)。请你设计一个算法来计算可以获得的最大收益。class Solution {public: /** * * @param prices int原创 2021-02-20 22:45:54 · 2335 阅读 · 0 评论 -
图论算法详解
一、图的表示1.1 邻接矩阵一个一维数组存储顶点。一个二维数组存储边。稠密图首选邻接矩阵。如果顶点太多了,比如说有100000个顶点,要开辟mpt[100000][100000]这么大的数组,空间超出限制,则考虑用邻接表。同时,如果图比较稀疏,也可考虑用邻接表。下面演示邻接矩阵的存储过程。#include <bits/stdc++.h>using namespace std;int mpt[105][105]; int n,m; //n个点,m条边 # define IN原创 2021-03-24 21:16:05 · 3647 阅读 · 0 评论 -
C++/C编程刷题经验
1.string(1)使用C++时,定义string变量。比较两个字符串时不用strcmp,而用“==”,“!=”,“>”,“<”,“>=”,“<=”。==”、 “!=”、 “<=”、 “>=”、 “<”和“>”操作符都可以用于进行string类型字符串的比较,这些操作符两边都可以是string字符串,也可以一边是string字符串另一边是字符串数组。#include <iostream>#include <string>us原创 2021-03-08 17:04:37 · 781 阅读 · 0 评论 -
DFS and BFS
1.深度优先搜索(1)DFS:所有路径都要走一遍(2)弊端:当搜索图为一张图时(非树),并且可走的路径很多,DFS会在某些点重复走,所用时间是极大的(而BFS一个点只走一次)。(3)有模板,只需稍微改动(4)特点:回溯题目描述:问题解决(可看做模板):主函数int main{ans=99999999,是为了最后如果走不出去输出-1?...原创 2021-03-05 10:23:26 · 1231 阅读 · 1 评论 -
【算法】动态规划与递归——感受动态规划是递推!注意,是推!
1.打家劫舍**注意:(1)一开始我只想到了隔一家偷一次,这些写出来的代码通过率还可以但是没想到,还有上图这样隔两家才是最好的偷法。(2)动态规划步骤一:定义子问题稍微接触过一点动态规划的朋友都知道动态规划有一个“子问题”的定义。什么是子问题?子问题是和原问题相似,但规模较小的问题。例如这道小偷问题,原问题是“从全部房子中能偷到的最大金额”,将问题的规模缩小,子问题就是“从 k个房子中能偷到的最大金额”,用 f(k)表示。步骤二:写出子问题的递推关系这一步是求解动态规划问题最关键的原创 2021-03-03 12:45:42 · 1070 阅读 · 0 评论 -
整数分划问题
一、问题描述 整数分划问题:对于一个正整数n的分划就是把n写成一系列正整数之和的表达式。要求给出分划方式与分划数目的总和 (例如: n=5)二、问题分析 这个问题用暴力搜索、循环、递归都能解决,但用递归是最灵活的,本题采用递归的方式求解。以n=5为例,手动列出正整数之和的表达式,可以发现以下规律:5 …各正整数不大于54+1 …各正整数不大于43+2 ,3+1+1原创 2020-08-15 14:57:15 · 1494 阅读 · 0 评论