刷题之路
程序刷题
炫橘子上火
玩笑人生
展开
-
LeetCode 121. 买卖股票的最佳时机
LeetCode 121. 买卖股票的最佳时机代码实现:class Solution {public: int maxProfit(vector<int>& prices) { int minPrice = 1e9, maxProfit = 0; for (auto price : prices) { maxProfit = max(maxProfit, price - minPrice);原创 2021-06-05 09:02:10 · 74 阅读 · 0 评论 -
LeetCode 56.合并区间
LeetCode 56.合并区间解题思路:参考了LeetCode官方的解答,基本思路就是先对intervals排序,排序之后intervals中每个数组[start, end]之间是连续的。此时我们看每个数组[start_i, end_i]中的start_i与前面的end相比,如果小于前一个的end,那么该[start_i, end_i],应该被合并区间[start, max(end, end_i)]中。代码实现:class Solution {public: vector<vec原创 2021-05-19 21:30:57 · 70 阅读 · 0 评论 -
【Rabin-Karp】字符串查找strStrⅡ
1、为什么使用Rabin-KMP?1、KMP算法复杂,且基本上只解决字符串查找(在一个字符串中查找另一个字符串)一类问题,时间复杂度为O(n+m),n和m为两字符串长度。而且很难理解为什么代码那样写,想要不出错的写出来其实是有些困难的,所以可使用较简单的Rabin-Kmp。2、若用普通双for循环实现的话,时间复杂度为O(n^2)。2、Rabin-KMP的基本思路简介普通方法在一个字符串source中查找另一个字符串target。比如source为abcde,target为cde,那我们会先用cde原创 2020-11-17 07:35:49 · 142 阅读 · 0 评论 -
LeetCode 31. 下一个排列
LeetCode 31. 下一个排列算法的思路参考了LeetCode官方解答:代码实现:class Solution {public: void nextPermutation(vector<int>& nums) { if (1 == nums.size()) return; int i, j; // 寻找较小数nums[i] for (i = nums.size() - 2; i >= 0;原创 2021-05-15 10:58:16 · 66 阅读 · 0 评论 -
【数学】POJ3420
题目:Quad Tiling在一个4N棋盘上,用12的骨牌平铺,有多少种方法?可以将整个棋盘分为两部分,一部分为不可分割的,另一部分为可分割的。如右边为不可分割的,左边为可分割的。那总的平铺数f(n)=可分割部分的平铺数*不可分割部分的平铺数。其中可分割部分全部情况为f(n-1),f(n-2),……,f(0)。所以,总的平铺数f(n)=f(n-1)*b(1)+f(n-2)*b(2)+……+f(0)*b(n),其中b(n)代表不可分割部分的平铺数。接下来,我们以不可分割部分入手。1、当右边部分是41原创 2020-06-30 22:48:10 · 193 阅读 · 0 评论 -
LeetCode 48.旋转图像
LeetCode 48.旋转图像解题思路:参考了leetcode官方的题解。最简单的方式是借助辅助的数组,将原数组中内容按照旋转规律放入辅助数组内,最后再将辅助数组中的内容放回原数组中。注:只要返回的结果是原数组,就认为是对原数组进行了修改。像这里利用辅助数组,之后将数值深度拷贝到原数组中就可以。但不能拷贝引用(浅拷贝),比如最后原数组内容不是数值上的拷贝辅助数组,而是辅助数组的引用,这样的话,也不算修改了原数组。除了上面借助辅助数组的方式实现原地旋转,还可以通过翻转实现。对原数组先水平翻转,再主对原创 2021-05-19 17:30:49 · 76 阅读 · 0 评论 -
【笔试——腾讯2021实习笔试题第二次2021.4.4】第3题 n人高空过钢索
本题类似于题目:POJ 1700 经典过河问题这是一道经典的过河问题,使用贪心算法。有两种策略:最快的(即所用时间t[0])和次快的过河,然后最快的将船划回来,再次慢的和最慢的过河,然后次快的将船划回来。即所需时间为:t[0]+2*t[1]+t[n-1]最快的和最慢的过河,然后最快的将船划回来,再最快的和次慢的过河,然后最快的将船划回来。即所需时间为:2*t[0]+t[n-2]+t[n-1]每次过河都比对两种方案,选花费最小的,保证耗时最少。另外,当只有人数n <= 2时,直原创 2021-04-05 22:16:34 · 869 阅读 · 2 评论 -
【最值型】LintCode 191.乘积最大的子序列
LintCode 191.乘积最大的子序列这也是一道最值型动态规划的典型题目,构建状态转移方程时,使用max和min。代码:class Solution {public: /** * @param nums: An array of integers * @return: An integer */ int maxProduct(vector<int> &nums) { if (0 == nums.size()) {原创 2021-05-08 20:46:42 · 90 阅读 · 0 评论 -
【存在型】LintCode 116. 跳跃游戏
LintCode 191. 跳跃游戏这是一道存在型动态规划的典型题目。这类题目写状态方程时,使用&&和||。代码:class Solution {public: /** * @param A: A list of integers * @return: A boolean */ bool canJump(vector<int> &A) { if (0 == A.size()) {原创 2021-05-08 20:42:15 · 90 阅读 · 0 评论 -
【Leetcode热题100】Leetcode 10. 正则表达式匹配
Leetcode 10. 正则表达式匹配题目描述:给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。‘.’ 匹配任意单个字符‘*’ 匹配零个或多个前面的那一个元素所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。代码用的动态规划,但完全参照答案,答案解析看的差不多理解,但这道题对目前的自己来说确实有难度,动态规划的各种类型接下来找时间都得学一学,不然还是差很多的。再此记录一下吧。代码:class Solution {public:原创 2021-03-11 21:25:03 · 96 阅读 · 0 评论 -
【计数型】LintCode 114. 不同的路径
LintCode 114. 不同的路径这是一道计数型动态规划的典型题目。写状态方程时要遵循不重复,不遗漏,然后将这些不同方案加起来构成状态转移方程。代码:class Solution {public: /** * @param m: positive integer (1 <= m <= 100) * @param n: positive integer (1 <= n <= 100) * @return: An integer原创 2021-05-08 20:38:33 · 213 阅读 · 0 评论 -
LeetCode 72. 编辑距离
LeetCode 72. 编辑距离使用动态规划代码实现:class Solution {public: int minDistance(string word1, string word2) { vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1, 0));//初始化 for (int i = 0; i < word1.siz原创 2021-05-23 08:50:48 · 102 阅读 · 0 评论 -
LeetCode 64. 最小路径和
LeetCode 64. 最小路径和解题思路:属于坐标行动态规划。首先开一个二维的数组dp[m][n],dp[i][j]代表到第i行第j列为止的最小路径和。每个位置最小的路径和依赖于它的上一行和它的前一列,所以状态转移方程:dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];代码实现:class Solution {public: int minPathSum(vector<vector<int>>&原创 2021-05-19 22:37:36 · 55 阅读 · 0 评论 -
LeetCode 70. 爬楼梯
LeetCode 70. 爬楼梯解题思路:使用动态规划,类似于不同路径那道题,属于计数型动态规划。不同路径那种坐标型的动态规划,当前第i行第j列的方案树值取决于上一行和前一列各自贡献的加和。这道题,dp[i]只能从dp[i - 1]和dp[i - 2]过来,所以状态转移方程就是:dp[i] = dp[i - 1] + dp[i - 2]官方解答:注:要爬n个台阶,dp一开始要开n + 1大小。最后一个状态为dp[n],而非之前的dp[n -1]。下面给出两种代码实现,一种是普通的动规实现,另一种使原创 2021-05-19 23:15:20 · 65 阅读 · 0 评论 -
LeetCode 55.跳跃游戏
LeetCode 55.跳跃游戏之前在LintCode做过一遍,这又一遍啦~动态规划的思路:初始化一个bool数组dp[n],dp[i]代表能否到达当前位置,true为能到达。对于dp[i]而言,前面第j个位置如果能到达i的话,需要满足:dp[j] == true && j + nums[j] >= i,也就是j这个位置首先能到,然后从j这个位置能跳到i。之前用的动态规划,所以这次一上来就用动态规划做了一遍。然后看大家在LeetCode上的答案讨论,看到一个贪心的做法,很直接了原创 2021-05-19 20:40:42 · 112 阅读 · 1 评论 -
【动态规划——坐标型-最大最小值问题】Lintcode 110. 最小路径和
Lintcode 110. 最小路径和题目描述:给定一个只含非负整数的m*n网格,找到一条从左上角到右下角的可以使数字和最小的路径。你在同一时间只能向下或者向右移动一步这道题不难,使用坐标型动态规划的解法正常做就可以了。class Solution {public: /** * @param grid: a list of lists of integers * @return: An integer, minimizes the sum of all numbe原创 2021-02-27 08:11:12 · 409 阅读 · 0 评论 -
【动态规划】Lintcode 109. 数字三角形
109. 数字三角形题目描述:给定一个数字三角形,找到从顶部到底部的最小路径和。每一步可以移动到下面一行的相邻数字上。本题可以作为动态规划的题目入门。为了深刻理解,这里使用5种方法实现:DFS:遍历(Traverse)DFS:分治(Divide Conquer)记忆化搜索(Divide Conquer + Memorize)动态规划(自底向上)动态规划(自顶向下)// 4. 动态规划(自底向上)class Solution {public: /** * @para原创 2021-02-25 22:16:15 · 149 阅读 · 0 评论 -
LeetCode 53. 最大子序和
LeetCode 53. 最大子序和解题思路:使用动态规划。开一个状态数组dp[n],dp[i]代表到i为止的最大子序和。考虑dp[i - 1]和dp[i]之间的关系,即已知到第i - 1为止的最大子序和,如何得到第dp[i]。转移关系为:dp[i] = max(dp[i - 1] + nums[i], nums[i])前面的子序和如果是负数的话,加上当前nums[i]会造成子序和变小,此时dp[i]直接为当前nums[i]。代码实现上,给出了普通的动态规划实现,和使用滚动数组优化的代码实现。/原创 2021-05-19 19:57:46 · 73 阅读 · 0 评论 -
【动态规划——坐标型-方案总数问题】Lintcode 114. 不同的路径
Lintcode 114. 不同的路径题目描述:有一个机器人的位于一个 m × n 个网格左上角。机器人每一时刻只能向下或者向右移动一步。机器人试图达到网格的右下角。问有多少条不同的路径?n和m均不超过100且答案保证在32位整数可表示范围内。属于坐标型动态规划中方案数的问题:class Solution {public: /** * @param m: positive integer (1 <= m <= 100) * @param n: p原创 2021-02-27 09:10:04 · 208 阅读 · 0 评论 -
【最值型】Lintcode 669. 换硬币
Lintcode 669. 换硬币代码:class Solution {public: /** * @param coins: a list of integer * @param amount: a total amount of money amount * @return: the fewest number of coins that you need to make up */ int coinChange(vector<int原创 2021-05-06 22:33:35 · 90 阅读 · 0 评论 -
【动态规划——接龙型(一维坐标型)】Lintcode 76. 最长上升子序列
Lintcode 76. 最长上升子序列题目描述:给定一个整数序列,找到最长上升子序列(LIS),返回LIS的长度。说明最长上升子序列的定义:最长上升子序列问题是在一个无序的给定序列中找到一个尽可能长的由低到高排列的子序列,这种子序列不一定是连续的或者唯一的。https://en.wikipedia.org/wiki/Longest_increasing_subsequence本题属于接龙型动态规划,严格来讲是一维形式的坐标型动态规划:class Solution {public:原创 2021-02-27 22:17:15 · 120 阅读 · 0 评论 -
【动态规划——接龙型(一维坐标型)】Lintcode 602. 俄罗斯套娃信封
Lintcode 602. 俄罗斯套娃信封题目描述:给一定数量的信封,带有整数对 (w, h) 分别代表信封宽度和高度。一个信封的宽高均大于另一个信封时可以放下另一个信封。求最大的信封嵌套层数。这道题如果用最常规的想法(类似【动态规划——接龙型(一维坐标型)】Lintcode 76. 最长上升子序列)处理的话,因为有两层循环,时间复杂度会超时。需要将原来算法中的第二层循环通过一定的优化去掉。这里先给出普通的方法(时间复杂度会超,无法AC),再给出优化之后的方法。//1. 普通方法,时间复杂度会超原创 2021-02-28 09:25:20 · 200 阅读 · 0 评论 -
【Leetcode热题100】Leetcode 5.最长回文字串
Leetcode 5.最长回文字串题目描述:给你一个字符串 s,找到 s 中最长的回文子串。这道题先使用接龙型动态规划,但时间复杂度超了。然后参考了解析,使用了坐标型动态规划,新开一个二维数组f[n][n],这里f[i][j]表示s[i]~s[j]的子字符串是否为回文串,若是f[i][j]=true,否则为false。然后维持一个最长的子串。判断是否为回文串时,利用特点:对于一个子串而言,如果它是回文串,并且长度大于 2,那么将它首尾的两个字母去除之后,它仍然是个回文串。class Solutio原创 2021-03-03 22:15:54 · 126 阅读 · 1 评论 -
LeetCode 62. 不同路径
LeetCode 62. 不同路径解题思路:属于计数型的动态规划,即计算方案数目的题型。这也是一道非常典型的坐标型动态规划题,之前在LintCode上做过,可能这是第四回做了,一看到之后立马就想到了动规,也就没有想别的方法。代码实现:class Solution {public: int uniquePaths(int m, int n) { //初始化 vector<vector<int>> dp(m, vector<int&原创 2021-05-19 21:58:29 · 60 阅读 · 0 评论 -
【最短路——Bellman_Ford算法】AcWing 853. 有边数限制的最短路
AcWing 853. 有边数限制的最短路[Bellman_Ford算法]这里有两个点需要说明一下:在下面代码中,是否能到达n号点的判断中需要进行if(dist[n] > INF/2)判断,而并非是if(dist[n] == INF)判断,原因是INF是一个确定的值,并非真正的无穷大,会随着其他数值而受到影响,dist[n]大于某个与INF相同数量级的数即可。本题比较特殊,下面代码中使用了backup[] 数组是上一次迭代后 dist[] 数组的备份,由于是每个点同时向外出发,因此需要对 d原创 2021-04-23 09:25:02 · 121 阅读 · 0 评论 -
【最短路——朴素Dijkstra】AcWing 849. Dijkstra求最短路 I
AcWing 849. Dijkstra求最短路 Im的数量级在n^2的级别,所以该最短路问题使用朴素版的Dijkstra算法。代码:#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N = 510;int n, m;int g[N][N];//该图为稠密图,所以使用邻接矩阵来存int dist[N];//每个点距起点的距原创 2021-04-17 20:01:41 · 146 阅读 · 0 评论 -
【最小生成树——Kruskal算法】AcWing 859. Kruskal算法求最小生成树
AcWing 859. Kruskal算法求最小生成树代码:#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N = 100010, M = 200010, INF = 0x3f3f3f3f;int n, m;int p[N];struct Edge { int a, b, w; bool op原创 2021-05-06 21:59:21 · 132 阅读 · 0 评论 -
【二分图——匈牙利算法】AcWing 861. 二分图的最大匹配
AcWing 861. 二分图的最大匹配代码://匈牙利算法求二分图最大匹配#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N = 510, M = 100010;int n1, n2, m;int h[N], e[M], ne[M], idx;int match[N];//右半部点对应的左半部点的编号bool st原创 2021-05-06 22:14:49 · 163 阅读 · 0 评论 -
【二分图——染色法】AcWing 860. 染色法判定二分图
AcWing 860. 染色法判定二分图代码:#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N = 100010, M = 200010;//无向图,边数为顶点数2倍int n, m;int h[N], e[M], ne[M], idx;int color[N];void add(int a, int b) {原创 2021-05-06 22:08:32 · 119 阅读 · 0 评论 -
【最短路——堆优化版的Dijkstra算法】AcWing 850. Dijkstra求最短路 II
AcWing 850. Dijkstra求最短路 II代码:#include <iostream>#include <cstring>#include <algorithm>#include <queue>using namespace std;typedef pair<int, int> PII;//first为当前节点距起点的距离,second为该节点编号const int N = 1e6 + 10;int n, m原创 2021-04-20 22:02:32 · 162 阅读 · 0 评论 -
【最短路——SPFA判断负环】AcWing 852. spfa判断负环
AcWing 852. spfa判断负环代码:#include <cstring>#include <iostream>#include <algorithm>#include <queue>using namespace std;const int N = 100010;int n, m;int h[N], w[N], e[N], ne[N], idx;int dist[N], cnt[N];bool st[N];void原创 2021-05-06 21:13:26 · 86 阅读 · 0 评论 -
【最短路——Floyd算法】AcWing 854. Floyd求最短路
AcWing 854. Floyd求最短路代码:#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N = 210;int n, m, Q;//Q表示询问int d[N][N];void floyd() { for (int k = 1; k <= n; ++k) for (int i = 1原创 2021-05-06 21:20:00 · 129 阅读 · 0 评论 -
【最小生成树——朴素版Prim算法】AcWing 858. Prim算法求最小生成树
AcWing 858. Prim算法求最小生成树代码:#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N = 510, INF = 0x3f3f3f3f;int n, m;int g[N][N];//邻接矩阵存稠密图int dist[N];//每个点到集合的最小距离bool st[N];//表示该点是否已经在连通块中原创 2021-05-06 21:53:04 · 199 阅读 · 0 评论 -
【最短路——SPFA】AcWing 851. spfa求最短路
AcWing 851. spfa求最短路SPFA,使用宽搜对bellman-ford算法做优化。算法流程如下:代码:#include <cstring>#include <iostream>#include <algorithm>#include <queue>using namespace std;const int N = 100010;int n, m;int h[N], w[N], e[N], ne[N], idx;原创 2021-05-06 21:08:58 · 83 阅读 · 0 评论 -
【AcWing——搜索与图论:深度优先搜索】843. n-皇后问题
【AcWing——搜索与图论:深度优先搜索】843. n-皇后问题这是第二次实现n皇后,之前使用hash实现的,当时只用了一种方法,就是提前看出每行只有一个皇后,然后考虑上下攻击和对角线攻击,这里使用两种方法,一种是设定每行只有一个皇后;另一种方法是直接暴解,遍历整个n*n的矩阵呢个,考虑每个格子放还是不放。// 方法一:设定每行只有一个皇后,找全排列#include <iostream>using namespace std;const int N = 20;int n;c原创 2021-04-02 21:01:34 · 150 阅读 · 0 评论 -
【深度优先搜索DFS】Lintcode 136. 分割回文串
Lintcode 136. 分割回文串题目描述:给定一个字符串,对其进行分割,分割后的每个部分都是回文串(这些分割后的部分能组成原字符串)。最后返回所有可能的这种回文串分割方案。可以记住一个结论:所有的切割问题都是组合问题。为什么这么说呢?比如对"abc"进行切割,可以在他们中间放数字变成:a1b2c,这样切割和组合的对应关系如下:切割方案:a | b | c 对应组合方案:[1, 2]切割方案:a | bc 对应组合方案:[1]切割方案:ab | c 对应组合方案:[2]切割方案:abc原创 2021-02-09 14:37:38 · 130 阅读 · 0 评论 -
【AcWing——深度优先搜索】AcWing 846. 数的重心
AcWing 846. 数的重心用数组进行邻接表存储方式,然后使用DFS进行图的遍历。#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N = 100010, M = N * 2;int n;int h[N], e[M], ne[M], idx;int ans = N;//全局原创 2021-04-14 08:30:35 · 206 阅读 · 0 评论 -
LeetCode 22. 括号生成
LeetCode 22. 括号生成第一种方法,直接使用暴力递归,搜索了全部可能情况,可以自己画一下递归树(从起始点开始,每个节点都有两个分支:‘(’ 和 ‘)’ )。第二种方法,对上面深度优先搜索进行可行性剪枝。我们可以只在序列仍然保持有效时才添加 ‘(’ or ‘)’,而不是像 方法一 那样每次添加。我们可以通过跟踪到目前为止放置的左括号和右括号的数目来做到这一点,如果左括号数量不大于 nn,我们可以放一个左括号。如果右括号数量小于左括号的数量,我们可以放一个右括号。解题思路和代码参考了LeetC原创 2021-05-10 22:28:10 · 87 阅读 · 0 评论 -
【深度优先搜索DFS】Lintcode 153. 数字组合 II
Lintcode 153. 数字组合 II题目描述:给定一个数组 num 和一个整数 target. 找到 num 中所有的数字之和为 target 的组合.Lintcode 135. 数字组合的简单变形,只是去除重复的时候考虑有些不同。class Solution {public: /** * @param num: Given the candidate numbers * @param target: Given the target number *原创 2021-02-08 21:05:11 · 149 阅读 · 0 评论 -
LeetCode 78. 子集
LeetCode 78. 子集代码实现:class Solution {public: void dfs(vector<vector<int>>& res, vector<int>& nums, vector<int>& subset, int start) { res.push_back(subset); if (start == nums.size()) { r原创 2021-05-31 08:13:23 · 68 阅读 · 0 评论