C++
Xiami2019
这个作者很懒,什么都没留下…
展开
-
二分查找模版
模版一:无需后处理left = 0, right = length - 1;while (left <= right) { mid = (left + right) / 2; if (nums[mid] == target) return mid; else if (nums[mid] < target) left = mid + 1; else right = mid - 1;}// 结束后:right + 1 == left// 每次都会询问nums[mid]是否等于ta原创 2021-01-28 10:10:42 · 124 阅读 · 0 评论 -
每日一题 由斜杠划分区域 LeetCode959
并查集问题,把每个单元格看作是四个小三角形,然后对各个小三角形进行合并。// 每一个单元格可以分为四个小单元格,然后根据每个位置的字符进行单元格内合并或单元格间合并class UnionFind {public: UnionFind(int n): f(n), count(n) { for (int i = 0; i < n; ++i) { f[i] = i; } } int findf(int x) {原创 2021-01-25 10:41:52 · 113 阅读 · 0 评论 -
每日一题 连通网络的操作次数 LeetCode1319
裸并查集,并根据图论知识判断,如果边数大于等于顶点数减一,就一定可以改造成连通图。// 坚韧不拔,我命由我不由天!// 因为边可以任意移动,所以只要边数大于等于计算机数减一,就一定可以连通// 所需要的最小操作数等于连通分量数减一class UnionFind {public: UnionFind(int _n): f(_n), setSize(_n, 1), n(_n), setCount(_n) { for (int i = 0; i < n; ++i) {原创 2021-01-23 09:29:20 · 133 阅读 · 1 评论 -
01背包问题变式 分割等和子集
LeetCode 416 分割等和子集这道题可以看成是01背包问题,总和为m,则问题可以改写为是否能选出一些元素,恰好填满容量为m / 2的背包。状态定义:dp[i][j]: 表示使用第0到第i个物品能否填满容量为j的背包;状态转移方程:设第i个物品的体积为nums[i];if nums[i] == j:此时一定可以填满,dp[i][j] = true;if nums[i] < j:此时分装上i和不装上i两种情况:dp[i][j] = dp[i - 1][j] (不装i的情况) ||原创 2021-01-22 20:37:22 · 264 阅读 · 0 评论 -
C++11的引用折叠
创建一个引用的引用,引用就会折叠。除了右值引用的右值引用折叠之后还是右值引用之外,其它的引用全部折叠成左值引用。X& &、X& &&、X&& &都折叠成X&X&& &&折叠为X&&参考博客...原创 2021-01-20 14:00:09 · 394 阅读 · 0 评论 -
每日一题 连接所有点的最小费用 LeetCode1584
由完全图构建最小生成树,主要有两种方法:1. Kruskal算法;2. Prim算法;Kruskal算法需要构建并查集检查每次新添加的边构不构成回路。// 本质是求解一个完全图的最小生成树;// 使用kruskal算法需要通过并查集判断连通性,使用Prim算法则不用;// 首先需要将所有边都提取到一个边集里面,然后对边长进行排序;// 每次选取最短的边,然后通过并查集判断连通性// lion is hungryclass DisjointSet {private: vector原创 2021-01-19 23:35:22 · 169 阅读 · 0 评论 -
经典DP 完全背包问题
完全背包是01背包的扩展,即每个物品是无限量供应的。LeetCode322 零钱兑换比较经典的完全背包问题。定义子问题:组成金额i所需要的最小硬币数状态:T(i) = 组成金额i所需要的最小硬币数,如果不能组成则用amount + 1表示,初始数组全部初始化成amount + 1T(i) = min(T(i - k) + 1) (k为不同面值的硬币)class Solution {public: int coinChange(vector<int>& coins,原创 2021-01-19 15:35:26 · 210 阅读 · 0 评论 -
每日一题 账户合并 LeetCode721
这个月LeetCode真的猛出并查集,学不会并查集谁也别想走。并查集方法最重要的方法就是对问题进行建模,使得问题用连通分量表示,并且转化为判断两点是否连通的问题。然后要思考在构建并查集的过程中要如何构建并查集。哈希表加并查集需要两个哈希表,分别将邮箱映射成index和映射到对应的用户的名字。把每个用户对应的邮箱地址看成是一个连通分量。构建连通分量时只需要把accounts数组中每个用户对应的邮箱地址合并起来就好。// 并查集class UnionFind {public: UnionF原创 2021-01-18 15:04:50 · 142 阅读 · 0 评论 -
经典DP问题:最长递增子序列和最长公共子序列
LIS问题:最长递增子序列(Longest Increasing Subsequence);LCS问题:最长公共子序列(Longest Common Subsequence);子序列(subsequence)和子串(substring)的概念:子序列不要求连续,而子串必须由连续的字符组成。LIS问题时间复杂度:O(n^2);空间复杂度:O(n);设置一个DP数组,维护每个位置的符号作为结尾的最小的序列长度;class Solution {public: int lengthOfLIS原创 2021-01-18 12:18:18 · 116 阅读 · 0 评论 -
每日一题 打砖块 LeetCode803
如何计算每次击碎砖块而消失的砖块数量和顶部相连的砖块不会掉落;击碎一个砖块,可能使得其它与之连接的砖块不再与顶部相连而消失;消失的砖块数量 = 击碎之前与顶部相连的砖块数量 - 击碎之后与顶部相连的砖块数量 - 1 (1就是直接被敲碎的那块砖)并查集的按秩优化的秩即可以指当前子树的高度rank,也可以指当前集合的结点总数size,此题按size优化很huochi如何使用并查集解决这个问题?消除一个砖块的效果是:一个连通分量被分成了两个连通分量;并查集的作用是:把两个连通分量合并成一个连通分原创 2021-01-16 23:29:14 · 100 阅读 · 0 评论 -
每日一题 移除最多的同行或同列石头 LeetCode947
这是一个图论问题,首先按照题意构建图。石头作为顶点。如果两个石头位于同一行或同一列,则认为这两个石头之间有一条边,即这两个石头位于同一个连通分支之内。由题中删除石头的规则可知,实际上就是不断删除连通分支之内的顶点。而每个连通分支最后都会剩下一个顶点。所以,可以移除的最大的石头数 = 石头总数 - 连通分支数。所以题目就转化为两步,首先要构建图,然后再计算图中的连通分支数。计算连通分支数一般有两类方法,一是使用DFS或BFS之类的搜索方法,二是使用并查集的方法。这里考虑并查集的方法并查集并查集回答原创 2021-01-15 11:28:55 · 132 阅读 · 0 评论 -
每日一题 冗余连接 LeetCode 684
基本是个裸并查集的题目,从edges数组中遍历每条边,并构造并查集。如果一条边的两个顶点,则这条边就是构成回路的最后一条边。又因为无向图是由一棵树加上一条额外的边所构成的,所以显然,这样的回路只存在一个,则这样的一条边就是所求。// 并查集class Solution {public: int findf(vector<int> &f, int nodes) { if (f[nodes] != nodes) { int father原创 2021-01-13 22:09:32 · 121 阅读 · 1 评论 -
C++中的左值右值,左值引用右值引用,以及std::move,std::forward函数的作用
C++11中左值和右值的概念比较关键。1. 左值和右值左值(lvalue)是放在赋值语句左边可以被赋值的值,左值必须在内存中有一个确定的地址。右值(rvalue)用来放在赋值语句右边,将自己的值取出赋给别的变量,右值没有一个确定的地址。2.引用引用是C++所做的语法优化,本质是靠指针来实现,引用相当于变量的别名。声明引用的时候必须初始化,且一旦绑定,就不能把引用绑定到其他对象。即引用必须初始化,不能对引用重定义。对引用的一切操作,都相当于对原始对象的操作。3.左值引用和右值引用左值引用:顾名原创 2021-01-12 15:48:21 · 344 阅读 · 0 评论 -
每日一题 滑动窗口最大值 LeetCode239
虽然是个做过的题,但是早上心烦意乱,基本还是纯抄leetcode题解。法一:优先队列要维护一个滑动窗口内的最大值,可以使用优先队列法,即使用一个最大堆来维护。为了判定当前最大值是否还存在于滑动窗口内,可以同时存储value和index,这样当每次向优先队列加入新元素时,可以将堆顶所有不属于当前窗口的元素都弹出,保证优先队列维持的最大元素是在滑动窗口中的元素。class Solution {public: vector<int> maxSlidingWindow(vector<原创 2021-01-12 14:31:06 · 93 阅读 · 0 评论 -
每日一题 旋转数组 LeetCode189
408牛逼数组翻转先翻转前k个,再翻转后面的,然后再整个翻转。核心就是翻转数组元素的函数。有个点要注意,要用k模一下数组长度n。class Solution {public: void reverseArray(vector<int>& nums, int start, int end) { // 对数组进行翻转 if (start >= end || start < 0 || end < 0) return; for (原创 2021-01-08 16:41:07 · 128 阅读 · 0 评论 -
每日一题 省份数量 LeetCode 547
这题的本质就是求联通分支。上一题刚刚用了并查集,再一看这题不就是一个裸并查集么。法一:并查集// 法一 并查集class Solution {public: int findf(vector<int>& f, int x) { //找一个结点的父结点; if (f[x] != x) { int father = findf(f, f[x]); f[x] = father; }原创 2021-01-08 16:18:27 · 83 阅读 · 0 评论 -
每日一题 除法求值 LeetCode 399
这道题的本质是个图论问题,应该将问题建模为一个有向图,将除法表达式的变量看作是图的顶点,除法与被除数通过弧的方向来表示,除法表达式的值看作是边的权值,所以只需判断除法表达式的两点在图中是否存在路径,并且路径上每段距离的乘积就是最终表达式的结果。法一:广度优先搜索先构造图的表达形式,这里采用临接表来存储图,然后进行广度优先搜索,如果从起点出发搜到了终点,则表示这两个点之间存在路径,则把每段路径的乘积计算出来即可。class Solution {public: vector<double&原创 2021-01-08 14:46:12 · 118 阅读 · 0 评论 -
每日一题:正则表达式匹配
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*‘的正则表达式匹配。‘.’ 匹配任意单个字符‘*’ 匹配零个或多个前面的那一个元素所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。说明:s 可能为空,且只包含从 a-z 的小写字母。p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。示例1:输入:s = “aa”p = “a”输出: false解释: “a” 无法匹配 “aa” 整个字符串。示例2:s = “aa”p .原创 2020-06-20 11:46:48 · 312 阅读 · 0 评论 -
C++的类型转换
《C++ Primer Plus》笔记C++自动执行很多类型转换:将一种算术类型的值赋给另一种算术类型的变量时,C++将对值进行转换;表达式中包含不同的类型时,C++将对值进行转换;将参数传递给函数,C++将对值进行转换;初始化和赋值进行的转换:C++允许将一种类型的值赋给另一种类型的变量。这样做时,值将被转换为接收变量的类型。将一个值赋给取值范围更大的类型通常不会导致什么问题,只是占用的字节更多而已。然而,将一个很大的long值赋给float变量将降低精度。因为float只有6位有效数.原创 2020-06-19 15:01:35 · 489 阅读 · 0 评论 -
C++共用体(Union)
《C++ Primer Plus》笔记共用体(union)是一种数据格式,它能够存储不同的数据类型,但只能同时存储其中的一种类型。也就是说,结构可以同时存储int、long和double,共用体只能存储int、long或double。共用体的句法与结构相似,但含义不同。例如:union one4all{ int int_val; long long_val; double double_val;};可以使用one4all变量来存储int、long或double,条件是在不同的时间进行;.原创 2020-06-15 13:55:14 · 275 阅读 · 0 评论 -
C++面向行的输入(getline和get)
《C++ Primer Plus》笔记getline()getline()函数读取整行,它使用通过回车键输入的换行符来确定输入结尾。要调用这种方法,可以使用cin.getline()。该函数有两个参数。第一个参数是用来存储输入行的数组的名称,第二个参数是要读取的字符数。如果这个参数为20,则函数最多读取19个字符,余下的空间用于存储自动在结尾处添加的空字符。getline()成员函数在读取指定数目的字符或遇到换行符时停止读取。getline()函数每次读取一行。它通过换行符来确定行尾,但不保存换行.原创 2020-06-09 21:37:18 · 371 阅读 · 1 评论 -
C++的类型转换
《C++ Primer Plus》笔记在同一个表达式中包含两种不同的算术类型时,C++将执行两种自动转换:首先,一些类型在出现时便会自动转换;其次,有些类型在与其他类型同时出现在表达式中时将被转换。自动转换:在计算表达式时,C++将bool、char、unsigned char、signed char和short值转换为int。具体地说,true被转换为1,false被转换为0。这些转换被称为整型提升(integral promotion)。还有其他一些整型提升:如果short比int短,则un.原创 2020-06-09 11:08:34 · 1192 阅读 · 0 评论 -
C++的浮点类型
《C++ Primer Plus》笔记C++有3种浮点类型:float(4字节)、double(8字节)和long double(16字节)。这些类型是按它们可以表示的有效位数和允许的指数最小范围来描述的。有效位(significant figure)是数字中有意义的位。C和C++对于大小的要求是float至少32位,double至少48位,且不少于float,long double至少和double一样多。这三种类型的有效位数可以一样多。然而,通常,float为32位,double为64位,lon.原创 2020-06-09 10:07:02 · 3081 阅读 · 0 评论 -
每日一题:和可被K整除的子数组
给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。示例:输入:A = [4,5,0,-2,-3,1], K = 5输出:7解释:有 7 个子数组满足其元素之和可被 K = 5 整除:[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]遇见子数组和的相关问题,优先考虑前缀和的做法。这里因为是整除的问题,所以前缀和需要用求模后的结果表示。class Solu.原创 2020-05-28 10:02:56 · 395 阅读 · 0 评论 -
每日一题:解码字符串
给定一个经过编码的字符串,返回它解码后的字符串。编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。示例1:s = “3[a]2[bc]”, 返回 “aaabcbc”.s = “3[a2[c.原创 2020-05-28 09:25:02 · 241 阅读 · 0 评论 -
每日一题:寻找重复数
给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。示例1:输入: [1,3,4,2,2]输出: 2示例2:输入: [3,1,3,4,2]输出: 3说明:不能更改原数组;时间复杂度小于O(n^2);空间复杂度为O(1);数组中只有一个重复数字,但它可能不只重复出现一次;将index和nums[index]之间连一条边,即从index可以转移到nums[ind.原创 2020-05-26 15:34:19 · 331 阅读 · 0 评论 -
每日一题:验证回文字符串
给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。示例1:输入: “aba”输出: True示例2:输入: “abca”输出: True解释: 你可以删除c字符。注意:字符串只包含从 a-z 的小写字母。字符串的最大长度是50000。使用贪心算法。设置两个指针分别指向字符串头和字符串尾,向中间判断是否是回文。如果第一次出现不相等,因为可以删除一个字符,所以可以再次判断[low+1, high]和[low, high - 1]这两个区间是不是回文字符串。# 贪.原创 2020-05-19 12:25:06 · 247 阅读 · 0 评论 -
每日一题:和为K的子数组
给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。示例1:输入:nums = [1,1,1], k = 2输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。说明:数组的长度为 [1, 20,000]。数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。采用前缀和的方法,依次计算每个位置的前缀和,并判断是否有减去k的前缀和出现,然后加上对应的前缀和出现的次数。class Solution {publi.原创 2020-05-15 16:04:57 · 266 阅读 · 0 评论 -
每日一题:快速幂
实现 pow(x, n) ,即计算 x 的 n 次幂函数。快速幂的基本思想就是,将指数转换成二进制形式,然后计算每一位1的贡献。class Solution {public: double quickMul(double x, long long N) { double ans = 1.0; // 贡献的初始值为x double xContribute = x; // 在对N进行二进制拆分的同时计算答案 whi.原创 2020-05-12 09:52:51 · 105 阅读 · 0 评论 -
C++ string和int相互转换
int转string使用std::to_string(int),返回一个转换好的string字符串;#include <string> // string, std::to_stringusing namespace std; int main(){ int n=100; string str=to_string(n); return 0;...原创 2020-05-02 15:51:58 · 563 阅读 · 0 评论 -
C++ list用法
C++的STL中的list容器实现了一个双向链表。函数接口:list::assign将新的内容分配个列表容器,替换当前内容;list::back()返回列表最后一个元素的引用;list::begin()返回指向列表头元素的迭代器;list::cbegin()返回指向列表头元素的常量迭代器;list::cend()返回指向列表尾元素下一个位置的常量迭代器;list::clea...原创 2020-05-02 15:37:45 · 276 阅读 · 0 评论 -
每日一题:数组中数字出现的次数
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。示例1:输入:nums = [4,1,4,6]输出:[1,6] 或 [6,1]示例2:输入:nums = [1,2,10,4,1,4,3,3]输出:[2,10] 或 [10,2]限制:2 <= nums <= 100...原创 2020-04-28 11:17:35 · 99 阅读 · 0 评论 -
每日一题:硬币
硬币。给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示法。(结果可能会很大,你需要将结果模上1000000007)示例1:输入: n = 5输出:2解释: 有两种方式可以凑成总金额:5=55=1+1+1+1+1示例2:输入: n = 10输出:4解释: 有四种方式可以凑成总金额:10=1010=5+510=5+1+1+1+1+110...原创 2020-04-23 12:04:30 · 210 阅读 · 0 评论 -
字节跳动高频:缺失的第一个正数
给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。示例1:输入: [1,2,0]输出: 3示例2:输入: [3,4,-1,1]输出: 2示例3:输入: [7,8,9,11,12]输出: 1提示:算法的时间复杂度应该为O(n),并且只能用常数级别的额外空间。寂寞围绕这电视,垂死坚持,在两点半消失索引作为哈希键值易证,缺失的最小正数一定小于或等于n+1...原创 2020-04-20 21:47:36 · 204 阅读 · 0 评论 -
每日一题:岛屿数量
给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。此外,你可以假设该网格的四条边均被水包围。示例1:输入:11110110101100000000输出: 1示例2:输入:11000110000010000011输出: 3解释: 每座岛屿只能由水...原创 2020-04-20 11:00:16 · 299 阅读 · 0 评论 -
每日一题:统计重复个数
由 n 个连接的字符串 s 组成字符串 S,记作 S = [s,n]。例如,[“abc”,3]=“abcabcabc”。如果我们可以从 s2 中删除某些字符使其变为 s1,则称字符串 s1 可以从字符串 s2 获得。例如,根据定义,“abc” 可以从 “abdbec” 获得,但不能从 “acbbe” 获得。现在给你两个非空字符串 s1 和 s2(每个最多 100 个字符长)和两个整数 0...原创 2020-04-19 15:41:36 · 127 阅读 · 0 评论 -
LeetCode笔记:最长有效括号
给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。示例1:输入: “(()”输出: 2解释: 最长有效括号子串为 “()”示例2:输入: “)()())”输出: 4解释: 最长有效括号子串为 “()()”法一:动态规划这个问题可以通过动态规划解决。定义一个dp数组,其中第i个元素表示以下标为i的字符结尾的最长有效子字符串的长度。将dp数...原创 2020-04-18 12:09:04 · 170 阅读 · 0 评论 -
二叉树的前、中、后序遍历(递归与迭代写法)
二叉树的前序遍历二叉树的前序遍历指先访问头结点,再访问左子树,再访问右子树。递归写法class Solution { vector<int> ans; void preorder(TreeNode* root) { if (root == NULL) return; ans.emplace_back(root->val); ...原创 2020-04-17 14:25:17 · 435 阅读 · 0 评论 -
C++ string类的substr函数
string substr (size_t pos = 0, size_t len = npos) const;pos: substr开始的第一个字符的位置;len:substr的长度;例子:string str;str.substr(3, 5):substr包含从第三个字符开始的五个字符;str.substr(3):substr包含从第三个字符开始一直到字符串末尾的字符;...原创 2020-04-08 16:28:59 · 525 阅读 · 0 评论 -
合并K个排序链表
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。示例1:输入:[1->4->5,1->3->4,2->6]输出: 1->1->2->3->4->4->5->6方法一:K阶归并/*方法1:k阶归并*/class Solution {public: ListNode* ...原创 2020-04-07 20:01:56 · 85 阅读 · 0 评论