算法刷题
文章平均质量分 50
刷算法题过程中的一些笔记
Xu_221
大雾四起,我在无人处爱你,大雾散尽,我爱你人尽皆知。
展开
-
剑指 Offer 13. 机器人的运动范围
题目描述地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?示例 1:输入:m = 2, n = 3, k = 1输出:3示例 2:输入:m =原创 2022-05-17 09:30:00 · 120 阅读 · 0 评论 -
剑指 Offer 15. 二进制中1的个数
题目描述编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为 汉明重量).)。提示:请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。在 Java 中,编译器使用 二进制补码 记法来表示有符号整数。因此,在上面的 示例 3 中,输入表示有符号整数 -3。示例 1:输入:n = 11 (控原创 2022-05-16 10:00:00 · 95 阅读 · 0 评论 -
剑指 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。示例 1:输入: 2输出: 1解释: 2 = 1 + 1, 1 × 1 = 1示例 2:输入: 10输出: 36解释: 10 = 3 + 3 + 4, 3 × 3 ×原创 2022-05-15 12:00:00 · 116 阅读 · 0 评论 -
剑指 Offer 12. 矩阵中的路径
题目描述给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)。示例 1:输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,原创 2022-05-14 11:15:00 · 80 阅读 · 0 评论 -
剑指 Offer 11. 旋转数组的最小数字
题目描述把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为 1。注意,数组 [a[0], a[1], a[2], …, a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], …, a[n-2]] 。示例 1:输入:n原创 2022-05-13 09:00:00 · 123 阅读 · 0 评论 -
剑指 Offer 10- II. 青蛙跳台阶问题
题目描述一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。示例 1:输入:n = 2输出:2示例 2:输入:n = 7输出:21示例 3:输入:n = 0输出:1提示:0 <= n <= 100分析因为青蛙一次可以跳1级台阶或者2级台阶,可以当作动态规划问题,f[n]表示青蛙跳上一个n级台阶的总跳法数,那么最后一步有两原创 2022-05-12 13:45:00 · 53 阅读 · 0 评论 -
剑指 Offer 10- I. 斐波那契数列
题目描述写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:F(0) = 0, F(1) = 1F(N) = F(N - 1) + F(N - 2), 其中 N > 1.斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。示例 1:输入:n = 2输出:1示例 2:输入:n = 5输出:5原创 2022-05-11 11:03:28 · 233 阅读 · 0 评论 -
剑指 Offer 09. 用两个栈实现队列
题目描述用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )示例 1:输入:[“CQueue”,“appendTail”,“deleteHead”,“deleteHead”][[],[3],[],[]]输出:[null,null,3,-1]示例 2:输入:[“CQueue”,“deleteHead”,“appendTail原创 2022-05-07 09:15:00 · 46 阅读 · 0 评论 -
剑指 Offer 06. 从尾到头打印链表
题目描述输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。示例 1:输入:head = [1,3,2]输出:[2,3,1]限制:0 <= 链表长度 <= 10000分析题目要求从尾到头返回,但是链表是从头到尾开始遍历,我们可以将链表先正序保存到数组中,然后再将数组反转。还有一种方法是将链表按顺序压入栈中,然后在弹出,因为栈是后进先出,所以刚好满足题意代码/** * Definition for singly-linked list. * struct L原创 2022-05-05 09:23:50 · 53 阅读 · 0 评论 -
剑指 Offer 07. 重建二叉树
题目描述输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。示例 1:Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]Output: [3,9,20,null,null,15,7]示例 2:Input: preorder = [-1], inorder = [-1]Output: [-1]限制:0 <= 节点个数 <= 5000分析在二原创 2022-05-04 09:13:16 · 46 阅读 · 0 评论 -
剑指 Offer 05. 替换空格
题目描述请实现一个函数,把字符串 s 中的每个空格替换成"%20"。示例 1:输入:s = “We are happy.”输出:“We%20are%20happy.”限制:0 <= s 的长度 <= 10000分析题目要求把空格替换成“%20”,如果s的长度为n,那么输出字符串的长度为n + 2 * m ,m为空格的个数首先统计空格的个数,记为m改变s的长度为n + 2 * m使用两个指针p1,p2,分别指向原始字符串的尾部,和现在字符串的尾部判断p1指向的值是不是为空原创 2022-05-03 09:49:18 · 63 阅读 · 0 评论 -
剑指 Offer 04. 二维数组中的查找
题目描述在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。示例:现有矩阵 matrix 如下:[[1, 4, 7, 11, 15],[2, 5, 8, 12, 19],[3, 6, 9, 16, 22],[10, 13, 14, 17, 24],[18, 21, 23, 26, 30]]给定 target = 5,返回 true。原创 2022-05-02 08:21:45 · 68 阅读 · 0 评论 -
剑指 Offer 03. 数组中重复的数字
题目描述找出数组中重复的数字。在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。示例 1:输入:[2, 3, 1, 0, 2, 5, 3]输出:2 或 3限制:2 <= n <= 100000分析数据范围:n≤100000 => O(nlogn) => 各种sort,线段树、树状数组、set/map、heap、拓扑排序、d原创 2022-05-01 11:34:53 · 68 阅读 · 0 评论 -
【第二章】队列
文章目录一、队列二、具体操作实例一、队列先进先出二、具体操作1,在队尾插入元素,在队头弹出元素int q[N], hh, tt = -1;2,插入q[ ++ tt] = x;3,弹出hh ++ ;4,判断队列是否为空hh <= tt ? "NO" : "YES"5,取队头元素q[hh];实例实现一个队列,队列初始为空,支持四种操作:push x – 向队尾插入一个数 x;pop – 从队头弹出一个数;empty – 判断队列是否为空;query – 查询转载 2022-01-19 10:22:47 · 126 阅读 · 0 评论 -
【第二章】链表
文章目录前言一、单链表1,具体操作二、双链表前言链表可以使用结构体+指针的方式实现,但是这种方式的效率很低,所以这里分别介绍了使用数组来实现单链表和双链表的方法。提示:以下是本篇文章正文内容,下面案例可供参考一、单链表单链表中最常用的是邻接表(n个链表),邻接表的作用主要是存储树和图。1,具体操作单链表需要两个数组来分别存储节点的值和节点的next指针。实现一个单链表,链表初始为空,支持三种操作:向链表头插入一个数;删除第 k 个插入的数后面的数;在第 k 个插入的数后插入一个数。原创 2021-12-18 17:15:44 · 93 阅读 · 0 评论 -
【第一章】双指针算法
文章目录前言一、代码模板二、简单使用例一:最长连续不重复子序列例二: 数组元素的目标和总结前言双指针算法应用的非常广泛,前面讲到的快速排序、归并排序其实都是一种双指针算法。双指针算法包括:两个指针分别指向两个不同的序列;两个指针指向一个序列(这种是比较常见的情况)。提示:以下是本篇文章正文内容,下面案例可供参考一、代码模板一般双指针算法都会有以下形式:for(int i=0,j=0;i<n;i++){ while(j<i&&check(i,j)) j++;原创 2021-12-10 09:52:09 · 133 阅读 · 0 评论 -
【第一章】位运算
文章目录一、位运算常用操作二、使用案例一、位运算常用操作1,求n的二进制表示(最右边为第0位)中第k位是几1)先把第k位移到最后一位:n>>k2)看个位是几:x&1综上:n>>k&12,lowbit(x):返回x的最后一位1(最右边的1)1)lowbit(1010)=10;lowbit(101000)=10002)实现:x&(-x)=x&(~x+1)例如:x=1010…10…0;~x=0101…01…1;~x+1=0101…10原创 2021-12-11 17:46:43 · 446 阅读 · 0 评论 -
【第一章】整数离散化
文章目录前言一、具体操作二、使用案例前言整数离散化主要用于对于值域很大,而数目很少的数组,将这样的数组映射到一个值域也差不多的数组中。提示:以下是本篇文章正文内容,下面案例可供参考一、具体操作例如有一个数组a[]=[1,3,100,2000,50000],我们要将这个数组映射到b[]=[1,2,3,4,5]。1)a[]中可能有重复元素(去重)2)如何算出a[i]离散化之后的值(二分)具体的代码模板:vector <int> alls;//存储所有待离散化的值sort(al原创 2021-12-11 22:09:51 · 187 阅读 · 0 评论 -
【第二章】栈
文章目录一、栈二、具体操作3.实例一、栈先进后出二、具体操作1,压栈stk[++tt]=x2,弹出tt–3,栈顶stk[tt]4,栈是否为空if(tt>0) not emptyelse empty3.实例(1)实现一个栈,栈初始为空,支持四种操作:push x – 向栈顶插入一个数 x;pop – 从栈顶弹出一个数;empty – 判断栈是否为空;query – 查询栈顶元素。现在要对栈进行 M 个操作,其中的每个操作 3 和操作 4 都要输出相应的结果。输入格原创 2022-01-18 10:11:02 · 129 阅读 · 0 评论 -
【第一章】二分
文章目录前言一、整数二分二分出left区间:二分出right区间:如何选择上述两个模板二、浮点数二分总结例1:例二:前言二分的本质并不是单调性,面对单调性的题目可以二分,但是二分也可以用到非单调的题目。二分的本质是边界。提示:以下是本篇文章正文内容,下面案例可供参考一、整数二分如果存在一个性质,使得一个区间的左边不满足(下面即为left区间),而右边满足(下面即为right区间),左右区间不重合,那么我们可以使用二分来找到这个边界。二分出left区间:选定一个中间值:mid=(l+r+..原创 2021-12-05 20:03:36 · 65 阅读 · 0 评论 -
【第一章】归并排序
文章目录前言一、基本思路1.确定分界点x2.递归排序3.归并总结前言归并排序的思想也是分治提示:以下是本篇文章正文内容,下面案例可供参考一、基本思路1.确定分界点x这里的分界点为中间下标 mid=(l+r)/2 ,快速排序选的是值,而归并排序选取的下标。2.递归排序递归排序左右两边3.归并采用双指针算法合二为一采用两个指针分别指向左右两个区间的初始下标,即 l 和 mid 比较两个值q[l]和q[mid]的大小,把较小的值放到新的数组tmp中,并且较小值的下标加一,最后将没有搜..原创 2021-12-05 16:45:54 · 132 阅读 · 0 评论 -
【第一章】高精度
文章目录前言一、高精度加法二、高精度减法三、高精度乘法总结前言高精度主要是对c++语言而言,比如两个1e6相加减,一个数的长度为1e6和一个数为1e9相乘除,java里面有大整数类和python里面默认无穷大不需要考虑,而且高精度不常考,所以这里只介绍一些模板。提示:以下是本篇文章正文内容,下面案例可供参考一、高精度加法vector<int> add(vector<int> &A,vector<int> &B){ vector&l..原创 2021-12-07 19:46:39 · 1057 阅读 · 0 评论 -
【第一章】差分
文章目录前言一、一维差分例一二、二维差分例二:前言差分相当于前缀和的逆运算。提示:以下是本篇文章正文内容,下面案例可供参考一、一维差分有数组A[a1,a2,a3…an],构造数组B[b1,b2,b3…bn],使得ai=b1+b2+b3+…+bi,易知b1=a1,b2=a2-a1,b3=a3-a2…bn=an-a(n-1);不用考虑如何构造,只要每次进行差分就行。此时B就称为A的差分,A就称为B的前缀和。差分可以用于求一个数组的一部分区间[l,r]的每个数加上一个数c。这时我们让b(l)+=c原创 2021-12-08 22:14:15 · 83 阅读 · 0 评论 -
【第一章】快速排序
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、基本思路1.确定分界点x2.调整区间3.递归总结前言快速排序采用的是分治的思想提示:以下是本篇文章正文内容,下面案例可供参考一、基本思路1.确定分界点x可以是数组的左右边界、中间值或随机。2.调整区间使得第一个区间的值都小于等于x,第二个区间的值都大于等于x。###方法一:额外使用两个数组a,b,如果原数组q中的值小于x,放到数组a中,如果原数组q中的值大于x,放到数组b中,最后把a,b数组合并到原数原创 2021-12-05 14:10:28 · 1143 阅读 · 0 评论 -
【第一章】前缀和
文章目录前言一、后缀和前言比如一个数组里面的元素有[a1,a2,a3,a4…an],前缀和Si=a1+a2+…+ai;注意要让下标从1开始,S0=0;前缀和可以用来计算从[l,r]之间元素的和:Sr-Sl-1。提示:以下是本篇文章正文内容,下面案例可供参考一、后缀和输入一个长度为 n 的整数序列。接下来再输入 m 个询问,每个询问输入一对 l,r。对于每个询问,输出原序列中从第 l 个数到第 r 个数的和。输入格式第一行包含两个整数 n 和 m。第二行包含 n 个整数,表示整数数列。原创 2021-12-08 08:14:29 · 161 阅读 · 0 评论 -
【第一章】区间合并
文章目录前言一、具体操作二、使用案例前言区间合并是指多个有交集的区间合并成一个区间实际采用的是贪心算法。提示:以下是本篇文章正文内容,下面案例可供参考一、具体操作(1)按区间左端点排序(2)扫描整个区间,将有交集的区间进行合并如何合并:1,假设每个区间为【l,r】2,如果前一个区间是下一个区间的子集,则第一个区间左右端点不变3,如果前一个区间和下一个区间有交集,则 r 更新为第二的区间的 r4,如果前一个区间和下一个区间无交集,则前一个区间左右端点不变,找到一个无法合并的区间,并把原创 2021-12-14 09:22:56 · 610 阅读 · 0 评论