
leetcode算法题库
leetcode算法题详解
Captain_zw
这个作者很懒,什么都没留下…
展开
-
【leetcode】90-子集 II【C/C++】
题目描述解题思路:这类题首先想到的就是递归 + 回溯。重点在于跳过重复元素的处理,我一开始是考虑的在每一次遍历剩余元素进行递归调用中直接跳过前面的重复节点仅处理重最后一个重复节点。结果发现这样会存在一个问题,例如【1、2、2】,结果集中就不会存在【1、2、2】、【2、2】,因为在每次遍历剩余元素中,我是直接先跳过重复节点,这样第一个2就被跳过了,后续的递归也都不会有第一个2存在的子...原创 2020-03-23 15:25:34 · 238 阅读 · 0 评论 -
【leetcode】81-搜索旋转排序数组【C/C++】
题目如下:解题思路:参考leetcode-33题,这道题实际上时间复杂度要求为O(lgn),因此需要用二分法,但不同之处在于有重复元素需要处理(直接二分会对诸如:[3、1、1],目标值1——得不到正确结果)。代码如下:class Solution {public: bool search(vector<int>& nums, int target...原创 2020-01-15 11:59:00 · 215 阅读 · 0 评论 -
【leetcode】80-删除排序数组中的重复项【C/C++】
题目如下:解题思路:本题刚开始的第一想法就是构建同一个空数组,再建立一个索引表(hash表),遍历每个元素并记录元素的访问次数,对不超过两次的元素则加入数组。但是题目明确要求不使用额外的数组空间,在O(1)的额外空间下完成。因此看了一下评论区的思路,发现只需要遍历一次,并维护一个结果集数组的长度即可。在遍历的过程中,当结果集数组长度小于2或者当前元素不等于当前结果集数组中倒数第二个...原创 2020-01-15 09:27:49 · 163 阅读 · 0 评论 -
【leetcode】79-单词搜索【C/C++】
题目如下:解题思路:本题首先想到的思路就是遍历每一个元素进行深度优先搜索DFS,当找到符合条件的字符顺序即返回。在一次DFS搜索过程中,对已经遍历过的元素我们需要将其标记为已搜索状态; 但在DFS前后需要注意的是,必须要保证执行前后程序面对问题的状态是相同的,因此当前问题缩小为子问题时所做的对当前问题状态产生影响的事情应该全部失效,那么就需要在回溯时还原现场从而避免出现下图的...原创 2020-01-14 15:12:54 · 378 阅读 · 0 评论 -
【leetcode】78-子集【C/C++】
题目如下:解题思路:方法一:本题因为数组无重复元素,那么子集一共就有 2^nums.size() 种情况。因此采用位运算,从数字 0 到2^nums.size() - 1,分别对每一个数进行二进制位运算,将对应位为 1 对应的数组元素加入临时数组,每处理完一个数就将当前临时数组加入结果集,并清空临时数组。代码如下:class Solution {public: ...原创 2020-01-13 10:28:11 · 155 阅读 · 0 评论 -
【leetcode】77-组合【C/C++】
题目如下:解题思路:DFS+ 剪枝 + 回溯 。注意进入每一层时的剪枝条件。代码如下:class Solution{public: vector<vector<int>> combine(int n, int k){ vector<vector<int>> res; //存放结果 ...原创 2019-11-04 10:01:33 · 164 阅读 · 0 评论 -
【leetcode】75-颜色分类【C/C++】
题目如下:解题思路:方法一、直接采用插入排排序或快速排序即可。代码如下:插入排序class Solution {public: //插入排序 void sortColors(vector<int>& nums) { for(int i = 1; i < nums.size(); i++){ ...原创 2019-11-01 13:06:22 · 228 阅读 · 0 评论 -
【leetcode】74-搜索二维矩阵【C/C++】
题目如下:解题思路:方法一:二维数组有序,因此可以从右上角开始找,那样每次只需左移或者下移,即 row++ 或 col-- ,最大时间复杂度为O(m+n) 。代码如下:class Solution {public: //从右上角开始,要么往下走,要么往左走,最坏时间复杂度O(m+n) bool searchMatrix(vector<vector&...原创 2019-10-31 16:14:06 · 424 阅读 · 0 评论 -
【leetcode】73-矩阵置0【C/C++】
题目如下:解题思路:第一想法是利用O(m+n)的额外空间,第一遍遍历矩阵,确定哪些行、列需要置0,第二遍置0。实际上只需要 O(1) 的额外空间即可,用matrix第一行和第一列记录该行该列是否有0,作为标志位但是对于第一行,和第一列要设置一个标志位,为了防止自己这一行(一列)也有0的情况。代码如下:class Solution {public: //关键思...原创 2019-10-30 10:37:14 · 266 阅读 · 0 评论 -
【leetcode】71-简化路径【C/C++】
题目如下:解题思路:本题思路较为简单,采取入栈的方法。先只考虑"/"之间的字符串:当遇到不是"."和".."时的字符串,则将当前元素入栈; 当遇到".."且栈不为空时,则出栈顶部元素; 其他情况不做处理。问题的关键在于如何识别一个和多个"/",利用string流的办法,先把"/"替换成空格,之后将string绑定到一个istringstream中,通过类似 cin 的方法...原创 2019-10-29 16:02:07 · 306 阅读 · 0 评论 -
【leetcode】70-爬楼梯【C/C++】
题目如下:解题思路:典型的动态规划题目,dp[n] = dp[n-1] + dp[n-2]。代码如下:class Solution {public: //典型的动态规划题,dp[n] = dp[n-1] + dp[n-2] int climbStairs(int n) { if(n == 1 || n == 2) //注意n为1和2的处理...原创 2019-10-28 11:30:13 · 191 阅读 · 0 评论 -
【leetcode】69-平方根【C/C++】
题目如下:解题思路:先指数增加,确定sqrt(x)的大致范围; 借着对已经确定的范围采用二分法,找到 x 的平方根。代码如下:class Solution {public: int mySqrt(int x) { long long res = 1; //指数增加,找出sqrt(x)的大致范围 while(res *...原创 2019-10-28 11:19:03 · 254 阅读 · 0 评论 -
【leetcode】67-二进制求和【C/C++】
题目如下:解题思路:长度补齐后进行计算。代码如下:class Solution {public: string addBinary(string a, string b) { int a_size = a.size(); int b_size = b.size(); //长度补偿 while(a_siz...原创 2019-10-28 10:40:16 · 195 阅读 · 1 评论 -
【leetcode】66-加一【C/C++】
题目如下:解题思路:本题只可能有三种情况:给定整数中最后一位不是数字9(如12341234); 给定整数中最后一位是数字9,但不全是数字99(如10991099); 给定整数所有位全是数字9(如99999999)那么对于上述情况1,直接在最后一位加1即可。 对于上述情况2,只需从后向前遍历数组,逢9进1,直至非9结束。 对于上述情况3,在最开始不需要与情况2区分,只需...原创 2019-10-28 09:39:46 · 216 阅读 · 0 评论 -
【leetcode】64-最小路径和【C/C 】
题目如下:解题思路:简单思路就是递归+暴力遍历,对每个元素考虑向左向右两条路径,但是时间复杂度高。这道题最好的解法是动态规划,因为其满足动态规划的条件,可列公式:dp(i, j) = grid(i, j) + min(dp(i-1, j), dp(i, j-1))。解题步骤如下:首先创建一个mxn 的数组dp[][],用于存放对应网格的每个节点到出发点的最短距离,即其对...原创 2019-10-25 12:59:34 · 216 阅读 · 0 评论 -
【leetcode】63-不同路径 II【C/C 】
题目如下:解题思路:本题采用第62题“不同路径”动态规划的思路,因为其不再是简单的向左向右选择移动。因为机器人只能向右向下走,因此网格内的第一行只能由其左方的节点到达,第一列元素只能由其上方节点到达。 对于第一列元素,当其左方元素值为0(表示不可达)或者其对应的obstacleGrid[x][0] = 1时,则将其需要置为0不可达;否则置为1,因为只有一条路径到达它; 对于第一...原创 2019-10-25 10:12:47 · 202 阅读 · 0 评论 -
【leetcode】40-组合总和II【C++】
题目如下:解题思路:思路与 组合总和 那道题相同,同样是 递归 + 回溯,但是要注意去除重复元素。代码如下:class Solution {public: vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { ...原创 2019-06-20 21:16:06 · 270 阅读 · 0 评论 -
【leetcode】39-组合总和【C++】
题目如下:解题思路:采用 递归 + 回溯 的方式,下面这个图对解题思路解释的很清楚(原图地址)。代码如下:class Solution {public: vector<vector<int>> combinationSum(vector<int>& candidates, int target) { v...原创 2019-06-16 14:23:54 · 246 阅读 · 0 评论 -
【leetcode】38-报数【C++】
题目如下:解题思路:首先需要理解题意,题目的意思是对序列前一个数进行报数:数列第一项为 1 ;那第二项就报数第一项有一个1,输出 11 ;然后第三项在第二项的基础上报数,报数两个1,输出 21 ;第四项根据第三项报数为一个1和一个2,输出 1112 ;以此类推。那么解决问题的核心思想就是,通过 递归调用 获取前一个序列,并对前一个序列按照上述规则进行遍历处理得到当前序列。代码如...原创 2019-06-15 16:51:40 · 365 阅读 · 0 评论 -
【leetcode】36-有效的数独【C++】
题目如下:解题思路:本题的核心就是确保:每一行中没有重复数字、每一列中没有重复数字、每个3 x 3 子数独内没有重复数字。简单思路即通过暴力求解遍历三次数独来求解,但实际上只需遍历一次数独即可: 建立每个行、列、块的布尔类型映射表,映射表元素为真表示当前位置对应元素出现过,为假表示未出现过; 之后逐行逐列遍历数独的元素,如果当前元素为非“ . ...原创 2019-06-14 16:04:01 · 461 阅读 · 0 评论 -
【leetcode】35-搜索插入位置【C++】
题目如下:解题思路:本题较为简单,直接采用二分法,代码如下:class Solution {public: int searchInsert(vector<int>& nums, int target) { int r = 0, l = nums.size() - 1; //二分法 while(r ...原创 2019-06-13 14:34:27 · 170 阅读 · 0 评论 -
【leetcode】34-在排序数组中查找元素的第一个和最后一个位置【C++】
题目如下:解题思路:题目要求时间复杂度为 O(log n) 级别,采用 二分法 分别查找左右边缘。代码如下:class Solution {public: vector<int> searchRange(vector<int>& nums, int target) { if(nums.empty() || target...原创 2019-06-10 13:17:28 · 623 阅读 · 0 评论 -
【leetcode】33-搜索旋转排序树组【C++】
题目如下:解题思路:由于题目对于时间复杂度的要求为 O(log n) 级别,所以直接思路就是采用二分搜索。对于旋转排序数组,可以发现:如果中间的数小于最右边的数组元素,则右半段是有序的; 如果中间的数大于最右边的数组元素,则左半段是有序的;只要在有序的半段里用首尾两个数组元素来判断目标值是否在这一区域内,这样就可以确定保留哪半边。代码如下:class Solution...原创 2019-06-05 09:52:53 · 148 阅读 · 0 评论 -
【leetcode】31-下一个排列【C++】
题目如下:解题思路:注意,题目要求的是下一个更小的序列,即相对目前序列的下一个最小的序列,例如 132 的下一个更小序列是 213 。具体思路详见代码及其注释部分。代码如下:class Solution {public: void nextPermutation(vector<int>& nums) { int l = num...原创 2019-06-04 11:30:59 · 256 阅读 · 0 评论 -
【leetcode】29-两数相除【C++】
题目如下:解题思路:本题的根本在于 被除数 可以减去多少次 除数。如果直接暴力求解,那么当被除数为2147483648除数为1 ,必然超时。切换问题思路,循环倍增 除数 直到再倍增时无法被 被除数 整除即停止,记录除数增大的 倍数 。然后将被除数减去目前的除数,并将除数恢复为初始值后进入下一次循环。最后结果就等于所有的记录的倍数相加。可参考下列公式来理解:// divi...原创 2019-06-03 15:29:37 · 824 阅读 · 1 评论 -
【leetcode】28-实现strStr()【C++】
题目如下:解题思路:分别对两个字符串 haystack 和 needle 设置移动标签 i 和 j,比较并顺序移动它们,当标签 j 第一次顺序移动至字符串 needle 的末尾时即找到第一个匹配的支付串。需要注意的时,当字符串部分匹配时需要回退字符串 haystack 的标签 i 。代码如下:class Solution {public: int strStr(s...原创 2019-05-28 10:04:56 · 423 阅读 · 0 评论 -
【leetcode】27-移除元素【C++】
题目如下:解题思路:先对数组排序,然后检索数组中瞒住条件的元素,用 count 记录满足条件的元素个数,用 flag 记录第一个满足条件元素的前一个元素的位置,之后向前移动后续的数组元素。代码如下:class Solution {public: int removeElement(vector<int>& nums, int val) { ...原创 2019-05-26 17:51:59 · 271 阅读 · 0 评论 -
【leetcode】26-删除排序数组中的重复项【C++】
题目如下:解题思路:遍历数组,跳过重复元素,设置一个计数器 flag 记录非重复元素。注意处理数组访问的边界情况。代码如下:class Solution {public: int removeDuplicates(vector<int>& nums) { int length = nums.size(); if(l...原创 2019-05-26 14:34:25 · 189 阅读 · 0 评论 -
【leetcode】25-K个一组翻转链表【C++】
题目如下:解题思路:同样采用 递归 来解决问题。思路类似两两交换链表中节点,先对前 K 个节点翻转,然后递归调用,递归结束的条件是当前剩余节点个数小于 K 个。代码如下:/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; *...原创 2019-05-25 14:12:34 · 860 阅读 · 0 评论 -
【leetcode】24-两两交换链表中的节点【C++】
题目如下:解题思路:方法一:暴力求解,每次交换分情况处理(超时):当前待交换的两个节点后续仍有两个及以上节点; 当前待交换的两个节点后续只有最后一个节点; 当前待交换的两个节点后续没有节点。代码如下:/** * Definition for singly-linked list. * struct ListNode { * int val; * ...原创 2019-05-22 16:46:48 · 357 阅读 · 0 评论 -
【leetcode】23-合并K个排序链表【C++】
题目如下:解题思路:分治法。简单来说就是不停的对半划分,比如k个链表先划分为合并两个k/2个链表的任务,再不停的往下划分,直到划分成只有一个或两个链表的任务,开始合并。举例子来说,比如合并6个链表,那么按照分治法,首先分别合并0和3,1和4,2和5,这样下次只需合并3个链表;之后再合并1和3,最后和2合并就可以了。代码中的k是通过 (n+1) / 2 计算的,加 1 是为了当n为...原创 2019-05-20 17:40:20 · 507 阅读 · 0 评论 -
【leetcode】22-括号生成【C++】
题目如下:解题思路:递归 + 剪枝,当左边括号大于等于右边括号数量时就可以继续往下递归,否者直接结束该部分的递归调用。左括号用 left 表示剩余数量,右括号用 right 表示剩余数量。递归结束的条件:一种是结果错误,当 right > left / right > n / left > n ,之后结束递归。 一种是结果正确正确的,当 left == 0 &a...原创 2019-05-17 15:28:21 · 471 阅读 · 0 评论 -
【leetcode】21-合并两个有序链表【C++】
题目如下:解题思路:方法一,模仿老师小学帮新学生们插入队伍,以l1作为站好的队列。需要注意的是,当以 l1 为基本队列时,对于 l2 元素等于 l1 元素时,直接插在其前部,否则可能出现错误。代码如下:/** * Definition for singly-linked list. * struct ListNode { * int val; * Li...原创 2019-05-16 13:29:49 · 749 阅读 · 1 评论 -
【leetcode】20-有效的括号【C++】
题目如下:解题思路:如果只包括一种括号,那么采用计数器方法进行匹配即可即可。但是本题包括 ‘ ( ’、‘ [ ’、‘ { ’ 三种括号,因此需要考虑不同括号出现的位置,采用计数器的方法行不通。所以最好的方法是采用 栈 来解决:初始化栈 S。 一次处理表达式的每个括号。 如果遇到开括号,将其存入栈顶即可,稍后处理。 如果遇到闭括号,那么检查栈顶元素。如果栈顶的元素是一个相同类...原创 2019-05-15 11:08:52 · 304 阅读 · 0 评论 -
【leetcode】19-删除链表的倒数第N个节点【C++】
题目如下:解题思路:前后指针(快慢指针)的方法。使用两个指针先指向链表头部,第一个快指针向后移动到第n+1 位,现在这两个指针相差 n 个节点。 之后通过同时向后移动两个指针来保持这个恒定的间隔,直到快指针到达最后一个结点。 此时慢指针指向从最后一个结点数起的第n+1个结点,重新将慢指针指向节点的next指针指向其下下个结点。 需要注意的是当链表长度 m = n 时...原创 2019-05-13 10:23:21 · 483 阅读 · 0 评论 -
【leetcode】18-四数之和【C++】
题目如下:解题思路:类似求三数之和,将数组排序后,使用双循环固定两个数,用双指针找另外两个数,通过比较与target的大小,移动指针。 注意重复元素。代码如下:class Solution {public: vector<vector<int>> fourSum(vector<int>& nums, int target)...原创 2019-05-10 15:13:22 · 429 阅读 · 0 评论 -
【leetcode】17-电话号码的字母组合【C++】
题目如下:解题思路:因为不确定字符串的长度,所以用递归 Recursion 来解。首先建立一个字典 dict_map,保存每个数字所代表的字符串;然后还需要一个变量 level,记录当前遍历字符串中的位置。在递归函数中首先判断 level,如果跟 digits 中数字的个数相等了,将当前的组合加入结果 res 中,然后返回。 否则通过 digits 中的数字到 dict_map ...原创 2019-05-09 17:01:42 · 450 阅读 · 0 评论 -
【leetcode】16-最接近的三数之和【C++】
题目如下:解题思路:思路同求三数之和,仍旧是将数组排序后,将三个数的问题转化为两个数的问题。固定基数 base ,然后用双指针 left 和 right 向中间移动查找。代码如下:class Solution {public: int threeSumClosest(vector<int>& nums, int target) { ...原创 2019-05-07 10:52:44 · 131 阅读 · 0 评论 -
【leetcode】15-三数之和【C++】
题目如下:解题思路:先将数组排序,之后问题由三个数的问题转化为两数之和问题:a+b+c=sum => a+b=sum-c 。固定基数base,然后用双指针left和right向中间移动查找。代码如下:class Solution {public: vector<vector<int>> threeSum(vector<...原创 2019-05-05 09:47:58 · 1401 阅读 · 0 评论 -
【leetcode】14-最长公共前缀【C++】
题目如下:解题思路:以第一个string为标准,找每一个字符串中的第 i 个字符与第一个string第 i 个字符判等,如果遇到不相等的,就将flag置false并返回。代码如下:class Solution {public: string longestCommonPrefix(vector<string>& strs) { i...原创 2019-04-30 16:46:27 · 373 阅读 · 0 评论