每日一题
popul
这个作者很懒,什么都没留下…
展开
-
平衡二叉树
题目描述:给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。代码思路:如果使用自底向上的做法,则对于每个节点,函数height 只会被调用一次。自底向上递归的做法类似于后序遍历,对于当前遍历到的节点,先递归地判断其左右子树是否平衡,再判断以当前节点为根的子树是否平衡。如果一棵子树是平衡的,则返回其高度(高度一定是非负整数),否则返回 −1。如果存在一棵子树不平衡,则整个二叉树一定不平衡。代码实现:c原创 2021-04-23 16:44:52 · 72 阅读 · 0 评论 -
2021-04-23
题目描述:给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。代码思路:思路和算法:这是一种最朴素的方法——深度优先搜索枚举 s中的每一个节点,判断这个点的子树是否和 t相等。如何判断一个节点的子树是否和 t相等呢,我们又需要做一次深度优先搜索来检查,即让两个指针一开始先指向该节点和 t 的根,然后「同步移动」两根指针来「同步遍历」这两棵树,判断对应位置是否相等。代码实现:原创 2021-04-23 15:26:37 · 74 阅读 · 0 评论 -
二叉树的后序遍历
题目描述:给定一个二叉树,返回它的 后序 遍历。代码实现:方法一:(递归)class Solution {public:void postorder(TreeNode* root,vector &ans){if(root==NULL)return ;postorder(root->left,ans);postorder(root->right,ans);ans.push_back(root->val);}vector postorderTraversal原创 2021-04-23 15:11:23 · 250 阅读 · 0 评论 -
二叉树的中序遍历
题目描述:给定一个二叉树的根节点 root ,返回它的 中序 遍历。解题思路:按照左子树->根节点->右子树顺序访问二叉树代码实现:方法一:(递归)class Solution {public:void inorder(TreeNode* root,vector &ans){if(root==NULL)return;inorder(root->left,ans);ans.push_back(root->val);inorder(root->r原创 2021-04-20 22:52:33 · 116 阅读 · 0 评论 -
二叉树的前序遍历
题目描述:给你二叉树的根节点 root ,返回它节点值的 前序 遍历。代码思路:前序遍历是指访问二叉树的顺序为:根节点->左子树->右子树代码实现:方法一:(迭代)class Solution {public:vector preorderTraversal(TreeNode* root) {vector result;if(!root)return result;stack<TreeNode*> S;S.push(root);while(!S.empty()原创 2021-04-20 21:40:45 · 148 阅读 · 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解题思路:我们可以实现这样一个递归函数,通过「同步移动」两个指针的方法来遍历这棵树,p 指针和 q指针一开始都指向这棵树的根,随后 p 右移时,q左移,p 左移时,q右移。每次检查当前 p 和 q节点的值是否相等,原创 2021-04-11 16:59:59 · 53 阅读 · 0 评论 -
相同的树
题目描述:给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。示例 1:输入:p = [1,2,3], q = [1,2,3]输出:true示例 2:输入:p = [1,2], q = [1,null,2]输出:false示例 3:输入:p = [1,2,1], q = [1,1,2]输出:false解题思路:深度优先搜索如果两个二叉树都为空,则两个二叉树相同。如果两个二叉树中有且只有一原创 2021-04-11 16:06:48 · 98 阅读 · 0 评论 -
二叉树的最大深度
题目描述:给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明: 叶子节点是指没有子节点的节点。示例:给定二叉树 [3,9,20,null,null,15,7],3/ 9 20/ 15 7返回它的最大深度 3 。解题思路:(1)深度优先搜索:斜体样式如果我们知道了左子树和右子树的最大深度 l和 r,那么该二叉树的最大深度即max(l,r)+1,而左子树和右子树的最大深度又可以以同样的方式进行计算。因此我们可以用「深度优先搜索」原创 2021-04-11 12:06:47 · 259 阅读 · 0 评论 -
单值二叉树
题目描述:如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时,才返回 true;否则返回 false。示例 1:输入:[1,1,1,1,1,null,1]输出:true示例 2:输入:[2,2,2,5,2]输出:false解题思路:递归遍历二叉树的节点,然后比较根节点与其左右孩子的值是否相同,相同返回true,不同返回false。代码实现:class Solution {public:bool isUnivalTree(TreeNode* r原创 2021-04-11 11:31:05 · 273 阅读 · 0 评论 -
最小栈
题目描述:设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。push(x) —— 将元素 x 推入栈中。pop() —— 删除栈顶的元素。top() —— 获取栈顶元素。getMin() —— 检索栈中的最小元素。示例:输入:[“MinStack”,“push”,“push”,“push”,“getMin”,“pop”,“top”,“getMin”][[],[-2],[0],[-3],[],[],[],[]]输出:[null,null,null,nu原创 2021-04-04 22:29:28 · 81 阅读 · 0 评论 -
两个栈实现队列
题目描述:请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):实现 MyQueue 类:void push(int x) 将元素 x 推到队列的末尾int pop() 从队列的开头移除并返回元素int peek() 返回队列开头的元素boolean empty() 如果队列为空,返回 true ;否则,返回 false说明:你只能使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, si原创 2021-04-04 20:11:39 · 143 阅读 · 0 评论 -
两个队列实现栈
题目描述:用两个队列实现一个栈,请实现他的两个函数Push 和 Pop,分别完成入栈和出栈功能。解题思路图:实现代码:#include #include #include using namespace std;template class Cstack {public:Cstack(){}~Cstack(){}void push(const T& val) {if (queue1.empty() && queue2.empty()) {queue1.原创 2021-03-30 21:38:13 · 80 阅读 · 0 评论 -
循环队列
题目描述:设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。循环队列的实现代码:#includeusing namespace std;class CicleQueue{public://构造队列原创 2021-03-29 22:21:53 · 354 阅读 · 0 评论 -
链表插入排序
题目描述:对链表进行插入排序。插入排序算法:插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。重复直到所有输入数据插入完为止。解题思路:1.首先判断给定的链表是否为空,若为空,则不需要进行排序,直接返回。2.创建哑节点 dummyHead,令 dummyHead.next = head。引入哑节点是为了便于在 head 节点之前插入节点。3.维护 lastSorted原创 2021-03-18 09:33:53 · 51 阅读 · 0 评论 -
返回环形链表的第一个节点
题目描述:给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。说明:不允许修改给定的链表。解题思路:一个非常直观的思路是:我们遍历链表中的每个节点,并将它记录下来;一旦遇到了此前遍历过的节点,就可以判定链表中存在环。借助哈希表可以很方便地实现。实现代码:clas原创 2021-03-18 08:40:15 · 107 阅读 · 0 评论 -
环形链表
题目描述:给定一个链表,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。如果链表中存在环,则返回 true 。 否则,返回 false 。解题思路:最容易想到的方法是遍历所有节点,每次遍历到一个节点时,判断该节点此前是否被访问过。具体地,原创 2021-03-17 22:17:48 · 66 阅读 · 0 评论 -
单词倒排
题目描述:说明:1、构成单词的字符只有26个大写或小写英文字母;2、非构成单词的字符均视为单词间隔符;3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排转换后也只允许出现一个空格间隔符;4、每个单词最长20个字母;输入描述:输入一行以空格来分隔的句子输出描述:输出句子的逆序示例1输入I//am??a\student输出student a am I解题思路:对于我们来说,有效的字符就是从‘A’~‘z’,当非有效字符的时候代表一个单词的结束。原创 2021-03-17 15:53:53 · 99 阅读 · 0 评论 -
骆驼命名法
题目描述:从C/C++转到Java的程序员,一开始最不习惯的就是变量命名方式的改变。C语言风格使用下划线分隔多个单词,例如“hello_world”;而Java则采用一种叫骆驼命名法的规则:除首个单词以外,所有单词的首字母大写,例如“helloWorld”。 请你帮可怜的程序员们自动转换变量名。输入描述: 输入包含多组数据。每组数据一行,包含一个C语言风格的变量名。每个变量名长度不超过100。输出描述: 对应每一组数据,输出变量名相应的骆驼命名法。输入例子: hello_worldnice_to_m原创 2021-03-17 15:14:07 · 304 阅读 · 0 评论 -
2021-03-16
题目描述:给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。进阶:尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?示例 1:输入: nums = [1,2,3,4,5,6,7], k = 3输出: [5,6,7,1,2,3,4]解释:向右旋转 1 步: [7,1,2,3,4,5,6]向右旋转 2 步: [6,7,1,2,3,4,5]向右旋转 3 步: [5,6,7,1,2,3,4]示例转载 2021-03-16 22:51:37 · 27 阅读 · 0 评论 -
转换成小写字母
题目描述:实现函数 ToLowerCase(),该函数接收一个字符串参数 str,并将该字符串中的大写字母转换成小写字母,之后返回新的字符串。示例 1:输入: “Hello”输出: “hello”示例 2:输入: “here”输出: “here”示例 3:输入: “LOVELY”输出: “lovely”实现代码:class Solution {public:string toLowerCase(string str) {string s="";for(int i=0;i<原创 2021-03-16 22:24:56 · 49 阅读 · 0 评论 -
找出两个链表中第一个相等节点
题目描述:编写一个程序,找到两个单链表相交的起始节点。解题思路:方法一: 暴力法对链表A中的每一个结点 i的值,遍历整个链表 B 并检查链表 B 中是否存在结点i的值相等。复杂度分析时间复杂度 : (mn)(mn)。空间复杂度 : O(1)O(1)。代码实现:class Solution {public:ListNode *getIntersectionNode(ListNode headA, ListNode headB) {ListNodeHa=headA;ListNodeHb原创 2021-03-16 13:56:03 · 539 阅读 · 0 评论 -
判断链表是否为回文结构
回文链表:是指链表对折起来,对应位置的元素相等题目描述:对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。测试样例:1->2->2->1返回:true解题思路:1、利用快慢指针找到中间的位置(起初均指向头结点,然后slow一次走一步,fast一次走两步。注意不需要区分链表结点个数是奇数还是偶数); 2、将后半部分指针翻转;原创 2021-03-16 12:22:35 · 207 阅读 · 0 评论 -
删除链表中的重复节点
题目描述:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5示例1输入{1,2,3,3,4,4,5}返回值{1,2,5}代码实现:class Solution {public:ListNode* deleteDuplication(ListNode* pHead) {if (pHead == NULL || pHead原创 2021-03-14 11:15:25 · 118 阅读 · 0 评论 -
链表分割
题目描述:现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针解题思路:(1)直接创建两个链表:一个链表存放小于x的元素,另一个存放大于或等于x的元素。(2)然后迭代访问整个链表,将元素插入before或者after链表末尾。一旦抵达链表末端,则表明拆分完毕,最后合并两个链表。代码实现:class Partition {public:ListNode* partition(Lis原创 2021-03-13 19:43:30 · 80 阅读 · 0 评论 -
按升序方式合并两个链表
题目描述:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。示例 1:输入:l1 = [1,2,4], l2 = [1,3,4]输出:[1,1,2,3,4,4]示例 2:输入:l1 = [], l2 = []输出:[]示例 3:输入:l1 = [], l2 = [0]输出:[0]代码实现:方法一(递归):class Solution {public:ListNode* mergeTwoLists(ListNode* l1, List原创 2021-03-13 09:20:00 · 629 阅读 · 0 评论 -
输出该链表中倒数第k个结点。
题目描述:输入一个链表,输出该链表中倒数第k个结点。示例1输入1,{1,2,3,4,5}返回值{5}代码实现:class Solution {public:ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {//当链表为空且k=0时无效if(pListHeadNULL&&k0){return NULL;}ListNodeahead=pListHead;//从k-1节点出发的指针ListN原创 2021-03-12 16:31:26 · 89 阅读 · 0 评论 -
返回链表的中间节点
题目描述:给定一个头结点为 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。示例 1:输入:[1,2,3,4,5]输出:此列表中的结点 3 (序列化形式:[3,4,5])返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。注意,我们返回了一个 ListNode 类型的对象 ans,这样:ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.nex原创 2021-03-12 10:46:56 · 625 阅读 · 0 评论 -
反转链表
题目描述:反转一个单链表。示例:输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1->NULL代码实现:class Solution {public ListNode reverseList(ListNode head) {ListNode prev = null;ListNode curr = head;while (curr != null) {ListNode next = curr.nex原创 2021-03-11 22:51:18 · 39 阅读 · 0 评论 -
移除链表元素
题目描述:给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。示例1:输入:head = [1,2,6,3,4,5,6], val = 6输出:[1,2,3,4,5]示例 2:输入:head = [], val = 1输出:[]示例 3:输入:head = [7,7,7,7], val = 7输出:[]提示:列表中的节点在范围 [0, 104] 内1 <= Node.val <= 5原创 2021-03-11 22:19:48 · 39 阅读 · 0 评论 -
剪绳子2020.12.24
题目描述:假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?能则返回True,不能则返回False。示例 1:输入: flowerbed = [1,0,0,0,1], n = 1输出: True示例 2:输入: flowerbed = [1,0,0,0,1], n = 2输出: Fa原创 2020-12-25 15:18:37 · 54 阅读 · 0 评论 -
跳跃的游戏2020.12.20
题目描述:这里有一个非负整数数组 arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i + arr[i] 或者 i - arr[i]。请你判断自己是否能够跳到对应元素值为 0 的 任一 下标处。注意,不管是什么情况下,你都无法跳到数组之外。示例 1:输入:arr = [4,2,3,0,3,1,2], start = 5输出:true解释:到达值为 0 的下标 3 有以下可能方案:下标 5 -> 下标 4 -> 下标 1 -> 下标原创 2020-12-20 21:16:25 · 56 阅读 · 0 评论 -
删除被覆盖的区间2020.12.16
题目描述:给你一个区间列表,请你删除列表中被其他区间所覆盖的区间。只有当 c <= a 且 b <= d 时,我们才认为区间 [a,b) 被区间 [c,d) 覆盖在完成所有删除操作后,请你返回列表中剩余区间的数目。示例:输入:intervals = [[1,4],[3,6],[2,8]]输出:2解释:区间 [3,6] 被区间 [2,8] 覆盖,所以它被删除了。提示:1 <= intervals.length <= 10000 <= interva原创 2020-12-16 23:18:54 · 55 阅读 · 0 评论 -
二分查找2020.12.10
题目描述:请实现有重复数字的有序数组的二分查找。输出在数组中第一个大于等于查找值的位置,如果数组中不存在这样的数,则输出数组长度加一。示例1输入5,4,[1,2,4,4,5]返回值3说明输出位置从1开始计算分析:首先判断有没有解,如果目标值小于数组最后一个数,那么一定有解。改变二分查找,如果mid大于等于于目标值,可能我们的这个mid可能是最优的可能不是,左边还有,那么我们选择的范围就是【start,mid】,最后得到结果。class Solution {public:/**原创 2020-12-10 23:57:33 · 116 阅读 · 0 评论 -
删除有序链表中的重复元素2020.12.9
题目描述:给出一个升序排序的链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素。例如:给出的链表为1 \to 2\to 3\to 3\to 4\to 4\to51→2→3→3→4→4→5, 返回1\to 2\to51→2→5.给出的链表为1\to1 \to 1\to 2 \to 31→1→1→2→3, 返回2\to 32→3.示例1输入{1,2,2}返回值{1}分析:定义两个指针变量,让一个指针指向头节点的前驱,一个指向头节点,让指针++往后走,直到遍历完链表中的所有元原创 2020-12-09 14:07:57 · 372 阅读 · 0 评论 -
序列化二叉树2020.12.7
题目描述:请实现两个函数,分别用来序列化和反序列化二叉树二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。例如,我们可以把一个只有根节点为1的二叉树序列化为"1,",然后通过自原创 2020-12-07 22:10:14 · 31 阅读 · 0 评论 -
划分链表2020.12.6
题目描述:给出一个链表和一个值 ,以 为参照将链表划分成两部分,使所有小于 的节点都位于大于或等于 的节点之前。两个部分之内的节点之间要保持的原始相对顺序。例如:给出 1->4->3->2->5->2和x=3返回 1→2→2→4→3→5示例1输入{1,4,3,2,5,2},3返回值{1,2,2,4,3,5}分析:新建两个节点head1与head2,分别为指向两个链表的头结点。把节点值小于x的节点链接到链表1上,节点值大等于x的节点链接到链表2上。最后把原创 2020-12-06 23:31:27 · 84 阅读 · 0 评论 -
两个链表的第一个公共结点2020.12.5
题目描述:输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)分析:设置两个指针,分别指向两个链表的头节点,先将ta的结点遍历一遍,看ta中有没有值与tb的头节点相同,如果有则返回,没有则将tb指向tb头节点的下一个结点,再将ta从头遍历一遍,看有无值与tb相等,循环此操作。直到找到相等的结点的值。class Solution {public:ListNode* FindFirstCommonNode( ListNod原创 2020-12-05 23:39:34 · 121 阅读 · 0 评论 -
丢棋子问题2020.12.3
题目描述:一座大楼有层,地面算作第0层,最高的一层为第 层。已知棋子从第0层掉落肯定不会摔碎,从第层掉落可能会摔碎,也可能不会摔碎。给定整数作为楼层数,再给定整数作为棋子数,返回如果想找到棋子不会摔碎的最高层数,即使在最差的情况下扔的最小次数。一次只能扔一个棋子。示例1输入10,1返回值10说明因为只有1棵棋子,所以不得不从第1层开始一直试到第10层,在最差的情况下,即第10层是不会摔坏的最高层,最少也要扔10次示例2输入3,2返回值2说明先在2层扔1棵棋子,如果碎了,试第1层原创 2020-12-04 17:53:49 · 472 阅读 · 0 评论 -
合并二叉树2020.12.4
题目描述:已知两颗二叉树,将它们合并成一颗二叉树。合并规则是:都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。例如:两颗二叉树是:Tree 11/ \3 2/5Tree 22/ 1 3\ 4 7合并后的树为3/ 4 5/ \ 5 4 7示例1输入{1,3,2,5},{2,1,3,#,4,#,7}返回值{3,4,5,5,4,#,7}分析:t1和t2两个节点相加有四种情况:(1)当t1为空,t2不为空原创 2020-12-04 17:17:46 · 165 阅读 · 0 评论 -
在二叉树中查找两个节点的最近公共祖先2020.12.2
题目描述:给定一棵二叉树以及这棵树上的两个节点 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。示例1输入[3,5,1,6,2,0,8,#,#,7,4],5,1返回值3分析:有四种情况:(1)当o1或o2任意一个为根节点时,那么两个节点的最近公共祖先就是根节点(2)当o1和o2一个在根节点的左树一个在右树时,最近公共祖先为根节点(3)当o1和o2都在左树时,最近公共祖先是左树节点(4)当o1和o2都在右树时,最近公共祖先是右树节点class Solution {pub原创 2020-12-02 22:23:10 · 209 阅读 · 0 评论