算法题
算法题
AquilaEAG
时间并不会改变什么,行动才会
展开
-
验证完全二叉树
1.题目给定一个二叉树,确定它是否是一个完全二叉树。2.思路层次遍历,每次往队列里面push当前节点的左子树、右子树若为完全二叉树,层次遍历中不可能出现遍历真节点之前遍历过空节点,如示例2所示,遍历7之前遍历3的左子树是空节点,直接false3.代码class Solution {public: bool isCompleteTree(TreeNode* root) { bool reachNull = false; // 记录是否已经遍历到null结果原创 2021-04-16 21:11:19 · 325 阅读 · 0 评论 -
验证回文字符串
1.题目给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。示例 1:输入: “aba”输出: True示例 2:输入: “abca”输出: True解释: 你可以删除c字符。注意:字符串只包含从 a-z 的小写字母。字符串的最大长度是50000。2.思路回文串的题目用双指针总是最清晰的,不过这道题目多了一个删除的选项,所以我们还需要进行一个判断,因为当遇到对应位置不匹配的字符时,是左指针右移还是右指针左移呢?不管哪种情况,只要剩下的部分是完全回文串即可,原创 2021-04-16 20:46:49 · 306 阅读 · 0 评论 -
最接近的三数之和
1.题目给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。示例:输入:nums = [-1,2,1,-4], target = 1输出:2解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。2.思路双指针法先让数组有序,也就是需要先对数组进行排序然后每次固定一个元素,再去寻找另外两个元素,也就是双指针3.代码cla原创 2021-04-16 19:43:58 · 56 阅读 · 0 评论 -
排序奇升偶降链表
1.题目给定一个奇数位升序,偶数位降序的链表,将其重新排序。输入: 1->8->3->6->5->4->7->2->NULL输出: 1->2->3->4->5->6->7->8->NULL2.思路按奇偶位置拆分链表,得1->3->5->7->NULL和8->6->4->2->NULL反转偶链表,得1->3->5->7->NU原创 2021-04-16 19:15:28 · 699 阅读 · 0 评论 -
最大正方形
1.题目在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内,找到只包含 ‘1’ 的最大正方形,并返回其面积。2.思路动态规划dp[i][j]表示以(i,j)为右下角的全为'1'的正方形最大边长3.代码class Solution {public: int maximalSquare(vector<vector<char>>& matrix) { if(matrix.size()==0 || matrix[0].size()==0)原创 2021-04-16 16:40:31 · 91 阅读 · 0 评论 -
132模式
1.题目给你一个整数数组 nums ,数组中共有 n 个整数。132 模式的子序列 由三个整数 nums[i]、nums[j] 和 nums[k] 组成,并同时满足:i < j < k 和 nums[i] < nums[k] < nums[j] 。如果 nums 中存在 132 模式的子序列 ,返回 true ;否则,返回 false 。进阶:很容易想到时间复杂度为 O(n^2) 的解决方案,你可以设计一个时间复杂度为 O(n logn) 或 O(n) 的解决方案吗?示例原创 2021-04-10 12:29:05 · 259 阅读 · 0 评论 -
盛最多水的容器
1.题目给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。说明:你不能倾斜容器。示例 1:输入:[1,8,6,2,5,4,8,3,7]输出:49解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。示例 2:原创 2021-04-10 12:18:01 · 90 阅读 · 0 评论 -
C++ 实现LFU缓存机制
实现LFU(最不经常使用缓存算法)leetcode题目链接请你为 最不经常使用(LFU)缓存算法设计并实现数据结构。实现 LFUCache 类:LFUCache(int capacity) - 用数据结构的容量 capacity 初始化对象int get(int key) - 如果键存在于缓存中,则获取键的值,否则返回 -1。void put(int key, int value) - 如果键已存在,则变更其值;如果键不存在,请插入键值对。当缓存达到其容量时,则应该在插入新项之前,使最不经常使原创 2021-04-09 10:34:20 · 359 阅读 · 0 评论 -
合并二叉树
1.题目给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。2.思路使用栈同时遍历两颗树的节点——先序遍历:根->左->右统一合并到第一颗树上3.代码/** * Definition for a binary tree node. * struct TreeNode { *原创 2021-04-08 21:28:27 · 63 阅读 · 0 评论 -
字符串拆分单词词组
1.题目给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。说明:分隔时可以重复使用字典中的单词。你可以假设字典中没有重复的单词。示例 1:输入:s = “catsanddog”wordDict = [“cat”, “cats”, “and”, “sand”, “dog”]输出:[“cats and dog”,“cat sand dog”]示例 2:输入:s原创 2021-04-08 21:06:00 · 870 阅读 · 0 评论 -
最长有效括号
1.题目给你一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长有效(格式正确且连续)括号子串的长度。示例 1:输入:s = “(()”输出:2解释:最长有效括号子串是 “()”示例 2:输入:s = “)()())”输出:4解释:最长有效括号子串是 “()()”示例 3:输入:s = “”输出:02.思路使用栈保存最近不合法的括号位置;每次合法位置-栈顶=合法字符串长度3.代码class Solution {public: /* 1. 使用原创 2021-04-08 20:06:08 · 78 阅读 · 0 评论 -
最小覆盖字串
1.题目给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。示例 1:输入:s = “ADOBECODEBANC”, t = “ABC”输出:“BANC”示例 2:输入:s = “a”, t = “a”输出:“a”2.思路滑动窗口,need表示还差多少个字符即可覆盖字符串t先右移完全覆盖t子串,再左移缩小边界,然后不断进原创 2021-04-08 19:35:00 · 436 阅读 · 0 评论 -
无序数组找中位数
1.无序数组找中位数思路一把无序数组排好序,取出中间的元素时间复杂度 采用普通的比较排序法 O(N*logN)如果采用非比较的计数排序等方法, 时间复杂度 O(N), 空间复杂度也是O(N).思路二(1)将前(n+1)/2个元素调整为一个小顶堆(2)对后续的每一个元素,和堆顶比较,如果小于等于堆顶,丢弃之,取下一个元素。 如果大于堆顶,用该元素取代堆顶,调整堆,取下一元素。重复2.2步(3)当遍历完所有元素之后,堆顶即是中位数。注:如果数组元素的个数是奇数,取数组前(size+1)原创 2021-04-04 10:34:38 · 5732 阅读 · 0 评论 -
快排思想实现Top K
快排实现Topk时间复杂度:平均O(N)利用快排的思想实现,每次可以得到一个元素下标,在这个元素下标左边,所有元素比这个元素小, 在这个元素右边,所有元素都比这个元素大:如果右边的元素个数等于K-1,则加上当前元素,达到K个,可知TOPK的元素为这K个;如果右边的元素个数小于K-1, 则在左边范围寻找K-len个元素如果右边的元素个数大于K-1, 则在右边范围寻找K个元素#include <iostream>#include <vector>using names原创 2021-04-04 09:40:30 · 1044 阅读 · 0 评论 -
快速排序 最坏时间复杂度
1.快速排序void quick_sort(vector<>int &q, int left, int right){ if(left > right) //截止条件:左右游标相遇 return; int i = left - 1; //-1,+1是为了后面while内保证两边端点元素加入判断 int j = right + 1; int x = q[(left + right)/2]; //将数据分成两部分:第一部分小于基数,第二部分大于基数 wh原创 2021-04-04 09:34:51 · 10188 阅读 · 0 评论 -
寻找二叉树的最近公共祖先
1.题目给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”示例 1:输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1输出:3解释:节点 5 和节点 1 的最近公共祖先是节点 3 。示例 2:输入:root = [3,5,1,6,2,0原创 2021-04-03 19:34:53 · 1549 阅读 · 0 评论 -
实现基本计算器(不含括号)
1.题目给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。整数除法仅保留整数部分。示例 1:输入:s = “3+2*2”输出:7示例 2:输入:s = " 3/2 "输出:1示例 3:输入:s = " 3+5 / 2 "输出:52.思路这道题因为没有括号所以相对来说简单很多,只要注意* / 这2个运算符优先级大于+ -即可。我们知道要让优先级高的先运算,那么就要把优先级低的加减运算先保存起来,所以用栈来保存+和-运算后的数字,对于乘除运算后面的数字我原创 2021-04-03 16:56:03 · 572 阅读 · 0 评论 -
二叉搜索树转换为双向链表
1.题目输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。为了让您更好地理解问题,以下面的二叉搜索树为例:我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需原创 2021-04-03 16:35:27 · 370 阅读 · 0 评论 -
搜索旋转排序数组
1.题目整数数组 nums 按升序排列,数组中的值 互不相同 。在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。给你 旋转后 的数组 nums 和一个原创 2021-04-03 11:17:25 · 71 阅读 · 0 评论 -
有效的括号字符串
1.题目给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:任何左括号 ( 必须有相应的右括号 )。任何右括号 ) 必须有相应的左括号 ( 。左括号 ( 必须在对应的右括号之前 )。* 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。一个空字符串也被视为有效字符串。示例 1:输入: “()”输出: True示例 2:输入: “(*)”输出: True示例 3:输入: “(*))”输出:原创 2021-04-03 10:24:15 · 211 阅读 · 0 评论 -
目标和
1.题目给定一个非负整数数组,a1, a2, …, an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。返回可以使最终数组和为目标数 S 的所有添加符号的方法数。示例:输入:nums: [1, 1, 1, 1, 1], S: 3输出:5解释:-1+1+1+1+1 = 3+1-1+1+1+1 = 3+1+1-1+1+1 = 3+1+1+1-1+1 = 3+1+1+1+1-1 = 3一共有5种方法让最终目标和原创 2021-04-03 10:00:49 · 108 阅读 · 0 评论 -
不用加减乘除做加法
1.题目写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。示例:输入: a = 1, b = 1输出: 22.思路(a&b)<<1 进位a^b 是非进位和 (不包含进位的结果)c++不支持负数的移位,需要加上转换为非负数后操作用a表示非进位和,b表示进位,当进位为0,则表示计算结束3.代码class Solution {public: int add(int a, int b) { w原创 2021-04-03 09:27:12 · 56 阅读 · 0 评论 -
滑动窗口最大值
1.题目给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值。示例 1:输入:nums = [1,3,-1,-3,5,3,6,7], k = 3输出:[3,3,5,5,6,7]解释:滑动窗口的位置 最大值[1 3 -1] -3 5 3 6 7 31 [3 -1 -3] 5 3 6 7 3原创 2021-04-02 21:50:36 · 169 阅读 · 0 评论 -
字符串解码
1.题目给定一个经过编码的字符串,返回它解码后的字符串。编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。示例 1:输入:s = “3[a]2[bc]”输出:“aaabcbc”示例 2:原创 2021-04-02 19:16:23 · 313 阅读 · 0 评论 -
C++实现LRU缓存机制
leetcode题目链接运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。实现 LRU Cache 类:LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,原创 2021-03-27 15:06:26 · 247 阅读 · 0 评论 -
二叉树的序列化与反序列化
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。示例:你可以将以下二叉树:1/ \2 3/ \4 5序列化为 “[1,2,3,null,null,4,5]”提示: 这与原创 2020-08-03 21:18:37 · 178 阅读 · 0 评论 -
二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]代码:/** * Definition for a binary tree node. * struct TreeNode { * int val; *原创 2020-08-03 20:46:28 · 133 阅读 · 0 评论 -
填充每个节点的下一个右侧节点指针
题目描述给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:struct Node { int val; Node *left; Node *right; Node *next;}填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。初始状态下,所有 next 指针都被设置为 NULL。示例解法1使用二叉树的层次遍历,通过一个current指针跟踪 next指针的填转载 2020-08-03 17:29:19 · 308 阅读 · 0 评论 -
二叉树的路径总和
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。说明: 叶子节点是指没有子节点的节点。示例:给定如下二叉树,以及目标和 sum = 22, 5 / \ 4 8 / / \ 11 13 4 / \ \ 7 2 1返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11原创 2020-08-02 00:56:47 · 419 阅读 · 0 评论 -
对称二叉树
给定一个二叉树,检查它是否是镜像对称的。例如,二叉树 [1,2,2,3,4,4,3] 是对称的。1/ \2 2/ \ / \3 4 4 3但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:1/ \2 2\ \3 3代码:/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left;原创 2020-08-01 23:26:01 · 111 阅读 · 0 评论 -
子集集合组合问题
题目给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。说明:解集不能包含重复的子集。示例:输入: nums = [1,2,3]输出:[[3],[1],[2],[1,2,3],[1,3],[2,3],[1,2],[]]思路回溯算法代码class Solution {public: vector<vector<int>> ans; int n; void backtrack(int firs原创 2020-08-13 16:28:17 · 304 阅读 · 0 评论 -
最小路径和
题目给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。说明:每次只能向下或者向右移动一步。示例:输入:[[1,3,1],[1,5,1],[4,2,1]]输出: 7解释: 因为路径 1→3→1→1→1 的总和最小。思路代码class Solution {public: int minPathSum(vector<vector<int>>& grid) { if (gr原创 2020-08-13 15:23:34 · 130 阅读 · 0 评论 -
leetcode 鸡蛋掉落问题
你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑。每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去。你知道存在楼层 F ,满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的鸡蛋都不会破。每次移动,你可以取一个鸡蛋(如果你有完整的鸡蛋)并把它从任一楼层 X 扔下(满足 1 <= X <= N)。你的目标是确切地知道 F 的值是多少。无论 F 的初始值如何,你确定 F 的值的最小移动次数是原创 2020-08-04 09:29:51 · 292 阅读 · 0 评论 -
字符串哈希
1.字符串哈希模板核心思想:将字符串看成P进制数,P的经验值是131或13331,取这两个值的冲突概率低小技巧:取模的数用2^64,这样直接用unsigned long long存储,溢出的结果就是取模的结果typedef unsigned long long ULL;ULL h[N], p[N]; // h[k]存储字符串前k个字母的哈希值, p[k]存储 P^k mod 2^64// 初始化p[0] = 1;for (int i = 1; i <= n; i ++ ){原创 2020-07-21 11:50:35 · 95 阅读 · 0 评论 -
联合体
#include <iostream>using namespace std;union { int i; char x[2];}a;int main() { a.x[0] = 16; a.x[1] = 1; cout << a.i << endl; return 0;}输出: 272原创 2020-10-19 19:14:34 · 59 阅读 · 0 评论 -
结构体大小
#include <iostream>using namespace std;struct { int i; union { char buff[13]; int i; }u; void foo() {} typedef char* (*f)(void *); enum {red,green, blue} color;}a;int main() { cout << sizeof(a) << endl; return 0;}输出原创 2020-10-19 19:10:41 · 66 阅读 · 0 评论 -
long long强转int, double强转int
1.测试代码#include <iostream>#include <bitset>using namespace std;int main() { //long long转int,直接截断 long long a = 0b0000111111111111111111111111111111111111111; std::cout << bitset<8 * sizeof(long long)>(a); cout << ",原创 2020-09-06 15:54:13 · 1266 阅读 · 0 评论 -
矩阵旋转
题目给定一个 n × n 的二维矩阵表示一个图像。将图像顺时针旋转 90 度。说明:你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。示例 1:给定 matrix =[[1,2,3],[4,5,6],[7,8,9]],原地旋转输入矩阵,使其变为:[[7,4,1],[8,5,2],[9,6,3]]示例 2:给定 matrix =[[ 5, 1, 9,11],[ 2, 4, 8,10],[13, 3, 6, 7],原创 2020-08-12 21:02:10 · 216 阅读 · 0 评论 -
构造全排列
题目给定一个 没有重复 数字的序列,返回其所有可能的全排列。示例:输入: [1,2,3]输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]思路1. 回溯算法2. STL代码1. 回溯算法class Solution {public: vector<vector<int>> permute(vector<int>& nums) { dfs(0, n原创 2020-08-12 20:31:04 · 236 阅读 · 0 评论 -
下一个排列
题目实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。必须原地修改,只允许使用额外常数空间。以下是一些例子,输入位于左侧列,其相应输出位于右侧列。1,2,3 → 1,3,23,2,1 → 1,2,31,1,5 → 1,5,1思路算法推导如何得到这样的排列顺序?这是本文的重点。我们可以这样来分析:我们希望下一个数比当前数大,这样才满足“下一个排列”的定义。因此只需要将后面的「大数」原创 2020-08-12 10:27:08 · 79 阅读 · 0 评论