剑指offer-2
剑指 Offer 22. 链表中倒数第k个节点 - 力扣(LeetCode)
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。
例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。
1 | /** |
剑指 Offer 24. 反转链表 - 力扣(LeetCode)
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
1 | /** |
剑指 Offer 25. 合并两个排序的链表 - 力扣(LeetCode)
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
1 | /** |
剑指 Offer 27. 二叉树的镜像 - 力扣(LeetCode)
请完成一个函数,输入一个二叉树,该函数输出它的镜像。
1 | /** |
剑指 Offer 28. 对称的二叉树 - 力扣(LeetCode)
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
递归的思想,一层一层的遍历
1 | /** |
剑指 Offer 30. 包含min函数的栈 - 力扣(LeetCode)
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
st1进行正常的栈逻辑,st2维护栈中最小的元素,将其放在栈顶。
1 | class MinStack { |
剑指 Offer 32 - I. 从上到下打印二叉树 - 力扣(LeetCode)
实际上就是层序遍历,层序遍历用队列比较合理
1 | /** |
剑指 Offer 32 - II. 从上到下打印二叉树 II - 力扣(LeetCode)
也是层序遍历,就是输出到二维数组中,而不是一个vector中。
1 | /** |
剑指 Offer 32 - III. 从上到下打印二叉树 III - 力扣(LeetCode)
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
在上一个题的基础上增加一个reverse函数判断
1 | /** |
剑指 Offer 26. 树的子结构 - 力扣(LeetCode)
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
1 | /** |
剑指 Offer 31. 栈的压入、弹出序列 - 力扣(LeetCode)
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。
可以用一个栈来模拟压入和弹出,如果最后栈为空就说明栈可以实现,
1 | class Solution { |
剑指 Offer 33. 二叉搜索树的后序遍历序列 - 力扣(LeetCode)
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true
,否则返回 false
。假设输入的数组的任意两个数字都互不相同。
1 | class Solution { |
剑指 Offer 34. 二叉树中和为某一值的路径 - 力扣(LeetCode)
给你二叉树的根节点 root
和一个整数目标和 targetSum
,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
本题是回溯的思想,主要包括先序遍历和路径记录两步。
先序遍历: 按照 “根、左、右” 的顺序,遍历树的所有节点。
路径记录: 在先序遍历中,记录从根节点到当前节点的路径。当路径为根节点到叶节点形成的路径,且各节点值的和等于目标值 sum 时,将此路径加入结果列表。
1 | /** |
剑指 Offer 35. 复杂链表的复制 - 力扣(LeetCode)
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
因为不知道random指针具体指向的是哪个元素,因此不能直接遍历复制,而是需要建立哈希表进行映射。
1 | /* |
剑指 Offer 36. 二叉搜索树与双向链表 - 力扣(LeetCode)
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
dfs函数进行中序遍历,左中右。pre和cur指针记录链表节点并进行双向连接。最后将头尾节点连接形成环形链表
1 | /* |
剑指 Offer 37. 序列化二叉树 - 力扣(LeetCode)
请实现两个函数,分别用来序列化和反序列化二叉树。
你需要设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
提示:输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。
1 | /** |
剑指 Offer 38. 字符串的排列 - 力扣(LeetCode)
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
1 | class Solution { |
剑指 Offer 39. 数组中出现次数超过一半的数字 - 力扣(LeetCode)
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
1 | class Solution { |
剑指 Offer 40. 最小的k个数 - 力扣(LeetCode)
1 | class Solution { |
剑指 Offer 41. 数据流中的中位数 - 力扣(LeetCode)
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
方法一:暴力法,会超时
1 | class MedianFinder { |
方法二:使用优先队列
1 | class MedianFinder { |
剑指 Offer 42. 连续子数组的最大和 - 力扣(LeetCode)
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
要求时间复杂度为O(n)。
动态规划,dp[i]指的是i之前的子数组最大和
1 | class Solution { |