算法题
贪心的鬼
孤独作酒
展开
-
输入一个数组表示完全二叉树,给定两个值,求这两个值所在节点的最近公共祖先节点的值
输入一个数组表示完全二叉树(数组中的值不重复),给定两个值(两个值不相等),求这两个值所在节点的最近公共祖先节点的值(没有则返回-1)原创 2022-09-02 09:32:39 · 454 阅读 · 0 评论 -
(C++)ACM模式输入方法总结
(C++)ACM模式输入方法总结1. 输入一个数/字符串2.只读取一个字符3. 整型/字符串 数组输入(固定个数)3. 整型/字符串 数组输入(非固定个数)4. 给定一行字符串,用逗号隔开,把它们存到数组中...原创 2022-08-20 23:44:45 · 3278 阅读 · 4 评论 -
智能指针shared_ptr
C++智能指针智能指针概述动态内存智能指针智能指针shared_ptr基本原理shared_ptr的一些操作构造函数和析构函数自定义运算符shared_ptr的使用注意事项智能指针概述动态内存在C++中,动态内存的管理是用一对运算符完成的:new和delete,new:在动态内存中为对象分配一块空间并返回一个指向该对象的指针delete:指向一个动态对象的指针,销毁对象,并释放与之关联的内存。动态内存管理经常会出现两种问题:一种是忘记释放内存,会造成内存泄漏;一种是尚有指针引用内存的情原创 2022-05-08 10:21:45 · 1047 阅读 · 1 评论 -
四数之和——双指针
四数之和三数之和【题意】给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。注意:答案中不可以包含重复的四元组。示例: 给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。 满足要求的四元组集合为: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0,原创 2022-04-30 14:05:22 · 257 阅读 · 0 评论 -
三数之和
三数之和【题目】给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。注意: 答案中不可以包含重复的三元组。示例:给定数组 nums = [-1, 0, 1, 2, -1, -4],满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]【解题思路】 首先将数组排序,然后有原创 2022-04-25 23:13:23 · 208 阅读 · 0 评论 -
前K个高频元素——使用优先级队列构建小根堆实现
前K个高频元素题目描述解题思路优先级队列 priority_queuepriority_queue构建大根堆、小根堆题目描述给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。示例 1:输入: nums = [1,1,1,2,2,3], k = 2输出: [1,2]示例 2:输入: nums = [1], k = 1输出: [1]提示:1 <= nums.length <= 105k 的取值范围是 [1, 数原创 2022-04-24 19:31:23 · 1546 阅读 · 0 评论 -
LRU算法实现
【题目描述】设计和构建一个“最近最少使用”缓存,该缓存会删除最近最少使用的项目。缓存应该从键映射到值(允许你插入和检索特定键对应的值),并在初始化时指定最大容量。当缓存被填满时,它应该删除最近最少使用的项目。它应该支持以下操作: 获取数据 get 和 写入数据 put 。获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之原创 2022-04-03 13:42:06 · 1037 阅读 · 0 评论 -
最长公共子序列
【题目描述】给定两个字符串text1和text2,返回的是这两个字符串的最长公共子序列的长度。若不存在,则返回0.一个字符串的子序列是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除)后组成的新字符串。两个字符串的公共子序列是这两个字符串所共同拥有的子序列。例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。【示例】输入:text1 = "abcde", text2 = "ace" 输出:3 解释:最.原创 2022-03-18 15:56:44 · 723 阅读 · 0 评论 -
最长递增子序列
【题目描述】给你一个整数数组nums,找到其中最长严格递增子序列的长度。子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7]是[0,3,1,6,2,2,7]的子序列【示例】输入:nums = [10,9,2,5,3,7,101,18]输出:4解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。输入:nums = [7,7,7,7,7,7,7]输出:1来源:力扣【动态规划步骤分析】(1)确定状态f[i] : .原创 2022-03-18 15:19:32 · 629 阅读 · 0 评论 -
买卖股票的最佳时机Ⅲ和Ⅳ
买卖股票的最佳时机1. 买卖股票的最佳时机Ⅲ1.1 问题描述1.2 动态规划步骤分析1.3 C++实现2. 买卖股票的最佳时机Ⅳ2.1 问题描述1.2 动态规划问题分析2.3 C++实现1. 买卖股票的最佳时机Ⅲ1.1 问题描述给定一个数组,它的第i个元素是一支给定的股票在第i天的价格设计一个算法计算你能得到的最大利润,最多可以完成两笔交易。注意:你不能同时参与多笔交易(必须在再次购买前出售掉之前的股票)【示例】输入:prices = [3,3,5,0,0,3,1,4]输出:6解释:在第原创 2022-03-13 16:27:24 · 1575 阅读 · 0 评论 -
买卖股票的最佳时机Ⅰ和Ⅱ
1. 买卖股票的最佳时机Ⅰ1.1 问题描述给定一个数组prices,它的第i个元素prices[i]表示一支给定股票第i天的价格。你只能选择某一天买入这只股票,并选择在未来的某一个不同的日子卖出该股票。设计一个算法来计算你能获取的最大利润。返回你可以从这笔交易中获得的最大利润,若不能获取任何利润。则返回0。【示例】输入:[7,1,5,3,6,4]输出:5解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 注原创 2022-03-13 10:26:53 · 1206 阅读 · 0 评论 -
打家劫舍问题总结
打家劫舍1. 打家劫舍Ⅰ1.1 题目描述1.2 动态规划步骤分析1.3 C++实现2. 打家劫舍Ⅱ2.1 题目描述2.2 动态规划步骤分析2.3 C++实现3. 打家劫舍Ⅲ3.1 题目概述3.2 动态规划步骤分析3.3 C++实现参考1. 打家劫舍Ⅰ1.1 题目描述 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两件相邻的房原创 2022-03-11 22:18:37 · 1093 阅读 · 1 评论 -
爬楼梯——进阶
【题目描述】假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个、... m个台阶。你有多少种不同的方法可以爬到楼顶呢?(m <= n)。【问题分析】1阶,2阶,.... m阶就是物品,楼层高度n就是背包.每一步可以跳不同的阶数,也可以调相同的阶数。(完全背包)先跳2阶再跳1阶,与先跳1阶再跳2阶是不同的。(排列问题)【动态规划步骤】(1)确定状态f[j] : 跳到j阶楼梯,有f[j]种方法。(2)转移方程f[i]有几种来源 最后一步原创 2022-03-11 15:00:13 · 410 阅读 · 0 评论 -
排列组合Ⅳ
给你一个由不同整数组成的数组`nums`,和一个目标整数target。请你从 `nums`中找出并返回总和为`target`的元素组合的个数。题目数据保证答案符合32位整数的返回。原创 2022-03-11 10:59:30 · 562 阅读 · 0 评论 -
一和零——动态规划
【题目描述】给你一个二进制字符串数组strs和两个整数m和n。请你找出并返回strs的最大子集的长度,该子集中最多有m个0和n个1。若x的所有元素也是y的元素,集合x是集合y的子集。【示例】输入:strs = ["10", "0001", "111001", "1", "0"], m = 5, n = 3输出:4解释:最多有 5 个 0 和 3 个 1 的最大子集是 {"10","0001","1","0"} ,因此答案是 4 。其他满足题意但较小的子集包括 {"0001","1"} 和 {"1原创 2022-03-10 10:48:42 · 179 阅读 · 0 评论 -
完全背包问题
有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。完全背包和01背包问题唯一不同的地方就是,每种物品有无限个。原创 2022-03-09 21:27:30 · 399 阅读 · 0 评论 -
目标和——动态规划
给定一个整数数组`nums` 和一个整数 `target`,向数组中的每个整数前添加`'+'`或`'-'`,然后串联起所有整数,使得他们的相加和等于target`,返回符合上诉构造方法,且运算结果等于`target`的不同表达式的数目。原创 2022-03-09 20:41:18 · 202 阅读 · 0 评论 -
分割等和子集——01背包应用
给定一个只包含正整数的非空数组,是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。注:每个元素中的元素不会超过100,数组大小不会超过200。原创 2022-03-09 15:51:07 · 357 阅读 · 0 评论 -
01背包问题
0-1背包1. 问题描述2. 0-1背包——二维数组2.1 状态分析2.2 转移方程2.3 初始化2.4 计算顺序2.5 举例推导数组f[i][j]2.5 C++实现3. 0-1背包——一维数组3.1 确定状态3.2 转移方程3.3 初始条件3.4 计算顺序3.5 C++实现1. 问题描述【0-1背包——问题描述】有n件物品和一个最多能背重量为w的背包。第i件物品的重量时weight[i],得到的价值为value[i]。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。注:每个物品只有原创 2022-03-08 20:15:08 · 151 阅读 · 0 评论 -
动态规划——题目类型、解题步骤及案例
动态规划——题目类型、解题步骤及案例1. 动态规划概述2. 题目类型3. 解题步骤4. 案例1:斐波那契数列5. 案例二:爬楼梯6. 案例三:使用最小花费爬楼梯1. 动态规划概述 “动态规划(Dynamic Programming, DP)在查找有很多重叠子问题的情况的最优解时有效。它将问题重新组合成子问题。为了避免多次解决这些子问题,它们的结果都逐渐被计算并被保存,从简单的问题直到整个问题都被解决。动态规划只原创 2022-03-07 18:18:16 · 419 阅读 · 0 评论 -
(三十八)修剪二叉树
【题目】给定二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树不应该改变保留在树中的元素的相对结构(即,如果没有被移除,原有的父代子代关系都应当保留)。可以证明,存在唯一的答案【示例】来源:力扣 669【解题思路】如果当前节点的元素小于low的数值,那么应该递归右子树,并返回右子树符合条件的头结点。如果当前节点的元素大于high的数值,那么应该递归左子树,并返回左子树符合条件的头结点。然后将下一原创 2022-01-06 20:04:17 · 502 阅读 · 0 评论 -
(三十七)删除二叉搜索树中的节点
【题目】给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。【要求】算法时间复杂度为 O(h)O(h)O(h),h 为树的高度。【解题说明】若该节点不存在,则直接返回NULL若该节点存在若该节点左右子树都为空,则直接删除该节点;若该节点的左子树存在,右子树为空,则删除节点,左孩子补位,返回左孩子为根节点若该节点的右子树存在,左子树为空,则删除节点,右孩子补位,返回右孩子为根原创 2022-01-06 13:03:05 · 357 阅读 · 0 评论 -
(三十六)通过有序数组生成平衡搜索二叉树
【题目】给定一个有序的数组sortArr,数种没有重复值,通过这个有序数组生成一棵平衡二叉树,并且该二叉树的中序遍历结果与数组一致。【解题思路】递归用有序数组中最中间的树生成搜索二叉树的头节点,然后这个树左边的树生成左子树,右边的树生成右子树。【举例】[1,2,3,4,5,6,7,8,9]【C++】TreeNode* generate(vector<int>& sortVec,int start,int end){ if(start > end) return原创 2022-01-06 10:54:29 · 516 阅读 · 0 评论 -
(三十五)在二叉树中找到两个节点的最近公共祖先
【题目】给定一棵二叉树的头节点head,以及这棵二叉树中的两个节点O1、O2,请返回O1和O2的最近公共祖先。【注意】所有节点的值都是唯一的。O1、O2为不同节点且均存在于给定的二叉树中【解题思路】如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。使用后序遍历,回溯的过程,就是从低向上遍历节点,一旦发现如何这个条件的节点,就是最近公共节点了。原创 2022-01-06 09:41:19 · 974 阅读 · 0 评论 -
(三十四)找到二叉树中的最大搜索二叉树
【题目】给定一棵二叉树的头节点head,已知其中所有节点的值都不一样,找到含有节点最多的搜索二叉树,并返回这颗子树的头节点。【要求】如果节点数为N,要求时间复杂度为O(N),额外空间复杂度为O(h),h为二叉树的高度【解题】树形dp套路第一步:分析答案的可能性第一种:X为头节点的子树中,最大的搜索二叉树就是X的左子树中的最大搜索二叉子树。即答案来自左子树第二种:X为头节点的子树中,最大的搜索二叉树就是X的右子树中的最大搜索二叉子树。即答案来自右子树第三种:若X左子树上的最大搜索二叉子树是X左原创 2022-01-04 20:47:29 · 549 阅读 · 0 评论 -
(三十三)判断二叉树是否是平衡二叉树
【平衡二叉树】一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。【树形dp套路】(程序员代码面试指南——左程云)如果题目求解目标是S规则,则求解流程可以定成以每个节点为头节点的子树在S规则下的每一个答案,并且答案一定在其中。步骤概述如下:(1)分析答案的可能性:以某个节点X为头节点的子树中,分析答案有哪些可能性,并且分析是以X的左子树、右子树和X整棵树的角度来考虑可能性的。(2)列出所需要的所有信息原创 2022-01-04 11:08:06 · 430 阅读 · 0 评论 -
(三十二)完全二叉树节点的个数
求一个节点个数为N的普通二叉树的节点的个数,可以直接遍历二叉树,求出节点个数。时间复杂度为O(N),可用递归法,层序遍历等方法,以下是递归法的代码:【C++】int getNodeNum(TreeNode* node){ if(node == NULL) return 0; int leftNum = getNodeNum(node->left); int rightNum = getNodeNum(no原创 2022-01-04 10:07:59 · 713 阅读 · 0 评论 -
(三十一)判断一个树是否是完全二叉树
【完全二叉树】定义一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树特点叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部。需要注意的是,满二叉树肯定是完全二叉树,而完全二叉树不一定是满二叉树性质[1] 具有n个结点的完全二叉树的深度(注:[ ]表示向下取整)[2] 如果对一棵有n个结点的完全二叉树的结点按层序编号, 则对任原创 2021-12-31 16:22:54 · 644 阅读 · 0 评论 -
(三十)二叉树的最小深度
【最小深度】最小深度是从根节点到最近叶子节点的最短路径上的节点数量。叶子节点是指没有子节点的节点【示例】最小深度为2【递归法】 如果左子树为空,右子树不为空,说明最小深度是 1 + 右子树的深度。反之,右子树为空,左子树不为空,最小深度是 1 + 左子树的深度。 最后如果左右子树都不为空,返回左右子树深度最小值 + 1 。int minDepth(TreeNode* node){ if(node ==原创 2021-12-31 15:34:07 · 1616 阅读 · 0 评论 -
(二十九)二叉树的最大深度
高度与深度高度和深度是相反的表示,深度是从上到下数的,而高度是从下往上数。某节点的深度是指从根节点到该节点的最长简单路径边的条数,而高度是指从该节点到叶子节点的最长简单路径边的条数。这里边的条数是规定根节点的深度和叶子节点的高度是0;所以树的深度和高度是相等的,而对其他节点来说深度和高度不一定相等。使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度...原创 2021-12-31 14:54:02 · 271 阅读 · 0 评论 -
(二十八)判断一个数是否是搜索二叉树
【二叉搜索树】节点的左子树的所有节点都小于当前节点;节点的右子树的所有节点都大于当前节点;所有的左子树和右子树自身必须也是二叉搜索树。【解题思路】只需改写二叉树的中序遍历,在遍历的时候判断节点值是否都是递增的即可。【注意】二叉搜索树中不存在相同元素pre的使用,避免了初始化时可能会初始化为节点元素【递归法】TreeNode* pre = NULL;//记录为最左面节点的数值bool isBST(TreeNode* root){ if(root == NULL)原创 2021-12-31 14:11:28 · 211 阅读 · 0 评论 -
(二十七)二叉树的ZigZag打印
二叉树的ZigZag打印解题思路:(双端队列)首先生成一个双端队列dq。把头部放入dq;原则一:如果从左往右打印,那么一律从dq的头部弹出节点,如果弹出的节点有子节点,先让左孩子从尾部进入dq,再让右孩子从尾部进入dq;如果弹出的节点没有子节点,则不需要放dq中。原则二:如果从右往左打印,那么一律从dq的尾部弹出节点,如果弹出的节点有子节点,先让右孩子从头部进入dq,再让左孩子从头部进入dq;如果弹出的节点没有子节点,则不需要放dq中。确定切换原则一与原则二的时机:下一层中最后打印的节点是当前原创 2021-12-24 21:09:43 · 676 阅读 · 0 评论 -
(二十六)二叉树的广度优先遍历(按层遍历)
二叉树的广度优先遍历(按层遍历)(1)层序遍历,输出到一行示例:【输出】1 2 3 4 5 6 7void levelOrder(TreeNode* head){ queue<TreeNode*> que; if(head != NULL){ que.push(head); } while(!que.empty()){ TreeNode* cur = que.front(); cout << cu原创 2021-12-24 20:51:09 · 1373 阅读 · 0 评论 -
(二十五)二叉树的递归与非递归遍历
二叉树的递归与迭代遍历概述1. 二叉树的递归序2. 二叉树的遍历方式1.递归遍历1.1 先序遍历1.2 中序遍历1.3 后序遍历2. 非递归遍历2.1 先序遍历2.2 中序遍历2.3 后序遍历3. 测试概述1. 二叉树的递归序而所谓的前中后序则为递归序中数字出现的次序前序(第一次出现):1,2,4,5,3,6,7中序(第二次出现):4,2,5,1,6,3,7后序(第三次出现):4,5,2,6,7,3,12. 二叉树的遍历方式深度优先遍历前序遍历(递归法,非递归法)中序遍历(原创 2021-12-24 20:26:27 · 816 阅读 · 0 评论 -
(二十四)翻转字符串里的单词
【题目】给你一个字符串 s ,逐个翻转字符串中的所有单词 。单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的单词分隔开。请你返回一个翻转 s 中单词顺序并用单个空格相连的字符串。【说明】输入字符串 s 可以在前面、后面或者单词间包含多余的空格。翻转后单词间应当仅用一个空格分隔。翻转后的字符串中不应包含额外的空格。【来源】力扣(LeetCode)【解题思路】删除字符串中多余空格将整个字符串反转反转单词string reserveWords(string s){原创 2021-12-22 15:36:43 · 284 阅读 · 0 评论 -
(二十三)替换字符串中的空格
【题目】请实现一个函数,把字符串 s 中的每个空格替换成"%20"。【来源】力扣【示例】【解题思路】计算字符串中的空格个数扩充数组大小,大小为替换空格后字符串的大小使用双指针法,分别指向旧长度的末尾、新长度的末尾;从后往前替换(避免移动元素的麻烦)【C++】string replaceSpace(string s){ int num = 0;//计算空格数; for (unsigned int i = 0;i < s.size();i++){ if(s[i] == " ")原创 2021-12-22 13:52:39 · 281 阅读 · 0 评论 -
(二十二)反转字符串Ⅱ
【题目】给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。如果剩余字符少于 k 个,则将剩余字符全部反转。如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。【来源】力扣(LeetCode)【示例】【题解思路】只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。//左闭右开void reverse(string& s,int sta原创 2021-12-22 10:32:18 · 331 阅读 · 0 评论 -
(二十)判断一个数是否是快乐数
【题目】判断一个数是否是快乐树,如果 n 是快乐数就返回 true ;不是,则返回 false 。「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。【示例】【解题思路】哈希表题目中加粗的"无限循环",说明求和的过程中,sum可能会重复出现,使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。【原创 2021-12-20 12:22:30 · 547 阅读 · 0 评论 -
(十九)有效的字母异位
【题目】给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。【示例】【解题思路】使用哈希表 因为数组就是一个简单的哈希表。定义一个数组叫做record用来记录字符串中字符出现的次数,大小为26并初始化为0;我们需要把字符映射到数组也就是哈希表的索引下标上,因为字符a到字符z的ASCII也是26个连续的数值。把字符a原创 2021-12-20 10:43:01 · 184 阅读 · 0 评论 -
(十八)两个单链表生成相加链表
【题目】假设每一个节点的值都在0~9之间,那么链表的整体就可以代表一个整数,例如9->3->7可以代表整数937。给定两个这种链表的头节点head1和head2,请生成代表两个整数相加值的结果【举例】【注意】先求出两个链表代表的自然数,然后求出两个整数的相加和,最后再将这个和转换为链表。因为链表可以代表的数很大,所以这种方式可能会造成溢出,不推荐【解题思路】(1)利用栈结构把两个链表分别从左到右遍历,遍历过程中将值压栈,这样就生成了两个链表的逆序栈,表示为s1,s2将s1,s2同原创 2021-12-20 08:54:36 · 662 阅读 · 0 评论