
剑指Offer
鲁大师啦啦啦
这个作者很懒,什么都没留下…
展开
-
二叉树的核心思想应用实例:二叉树镜像/二叉树的深度/平衡二叉树
关于 Tree 的最经典的递归套路 用主函数传参 root.left 和 root.right ,并用一个引用保存 同时也应该关注返回值以及返回结果 剑指 Offer 27. 二叉树的镜像 请完成一个函数,输入一个二叉树,该函数输出它的镜像。 class Solution { public TreeNode mirrorTree(TreeNode root) { // 首先进行判空操作 if(root == null){ return .原创 2022-04-07 19:33:50 · 412 阅读 · 0 评论 -
剑指 Offer 54. 二叉搜索树的第k大节点
给定一棵二叉搜索树,请找出其中第 k 大的节点的值。 首先要知道二叉树的前中后递归遍历 知道二叉搜索树的中序遍历是有序的 知道链表的第K大的节点就是 size-K class Solution { ArrayList<Integer> list = new ArrayList<>(); public int kthLargest(TreeNode root, int k) { inorder(root,list); // 第 K原创 2022-04-07 16:43:56 · 601 阅读 · 0 评论 -
剑指 Offer 53 - I. 在排序数组中查找数字 I
统计一个数字在排序数组中出现的次数。 题解 同样是使用HashMap来解题 但是发现效率并不高,后续再改进。 class Solution { HashMap<Integer,Integer> hashMap = new HashMap<>(); public int search(int[] nums, int target) { for (int i = 0; i < nums.length; i++) { if(原创 2022-04-07 11:46:01 · 469 阅读 · 0 评论 -
剑指 Offer 52. 两个链表的第一个公共节点
输入两个链表,找出它们的第一个公共节点。 题解 核心思想是利用两个链表的 节点和 相同 首先进行判空操作 循环的条件是只要两个节点的引用的地址(使用==)不相同,则继续循环 如果 A 链表的引用为空之后,将A链表的引用调整到B链表的头结点 B链表同理 最后返回任意一个节点的引用就是第一个公共节点 public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) {原创 2022-04-07 11:34:44 · 436 阅读 · 0 评论 -
剑指 Offer 50. 第一个只出现一次的字符
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。 题解 利用 HashMap 容器来解题 两次循环,注意第二次循环仍然是遍历字符串,而不是遍历容器的所有 value 值 class Solution { HashMap<Character,Integer> hashMap = new HashMap<>(); public char firstUniqChar(String s) { for (int原创 2022-04-06 22:00:19 · 219 阅读 · 0 评论 -
剑指 Offer 42. 连续子数组的最大和
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。 要求时间复杂度为O(n)。 题解 定义一个与原数组相同大小的数组 dp 默认原数组的第一个数为 连续子数组的最大值 maxNum dp[i-1] 是为保存上一个连续数组的最大值二设置的,方便下一个数据的计算 dp[i] 保存当前位置为 连续子数组最后一个数据的时候的最大值 核心是判断 dp[i-1] 的值是不是大于0 class Solution { public int maxSubArray(int原创 2022-04-06 21:32:09 · 203 阅读 · 0 评论 -
剑指 Offer 40. 最小的k个数
输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。 题解 最简单的思路就是对数组进行排序,然后再循环取前四个元素 class Solution { public int[] getLeastNumbers(int[] arr, int k) { int[] ret = new int[k]; Arrays.sort(arr); for(int i=0;i<k原创 2022-04-05 11:34:58 · 279 阅读 · 0 评论 -
剑指 Offer 39. 数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 题解:首先想到的常规解法是利用HashMap 首先引入 HashMap 数据结构 首先利用 hashmap.containsKey() 判断数组当前的值是否在容器中已经存在,如果不存在,直接将 value 值设为1。如果存在,则将通过 hashmap.get(nums[i])获取的 value 加1. 通过 for each 遍历容器的 key 值。 判断是否大于数组长度的一半 class Solution { Has原创 2022-04-05 11:26:06 · 663 阅读 · 0 评论 -
剑指 Offer 32 - I II III. 从上到下打印二叉树
从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。 层次遍历 题解 层次遍历首先应该想到的就是借助队列来实现。 在这里插入代码片原创 2022-04-05 09:46:55 · 143 阅读 · 0 评论 -
剑指 Offer 30. 包含min函数的栈
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。 题目表述:利用栈来实现得到最小元素的栈 题解 利用栈来实现入栈,出栈,得到栈顶元素,得到栈的入栈元素 利用一个栈来实现以上功能,核心是使用双入栈来保存最小值 定义一个栈和一个最小值,最小值初始化为栈的最大值 那么得到栈顶元素和返回最小值就很简单了 核心是入栈和出栈 入栈(双入栈):如果入栈的值比小于或等于当前最小值,那么先将原先的最小值入栈,最后再将当前原创 2022-04-04 17:18:45 · 405 阅读 · 0 评论 -
剑指 Offer 28. 对称的二叉树
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。 例如,二叉树 [1,2,2,3,4,4,3] 是对称的。原创 2022-04-03 15:35:20 · 414 阅读 · 0 评论 -
剑指 Offer 27. 二叉树的镜像
请完成一个函数,输入一个二叉树,该函数输出它的镜像。 题解 本题比较简单,核心思想就是先进行判空检验操作。 随后对左孩子和右孩子进行交换 核心就是对左右子树进行递归操作 最后返回根节点 class Solution { public TreeNode mirrorTree(TreeNode root) { // 首先进行判空操作 if(root == null){ return null; } if(r原创 2022-04-01 21:21:17 · 594 阅读 · 0 评论 -
剑指 Offer 25. 合并两个排序的链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4] 示例 2: 输入:l1 = [], l2 = [] 输出:[] 示例 3: 输入:l1 = [], l2 = [0] 输出:[0] 解题思路 双指针解法代码如下 /** * Definition for singly-linked list. * public class ListNode {原创 2022-03-10 20:28:57 · 251 阅读 · 0 评论 -
剑指 Offer 22. 链表中倒数第k个节点
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。 例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。 解题思路 先让临时指针先移动 倒数k - 1 步。 然后对临时指针所处位置进行循环判断。只有临时指针不为空,另一个指针随临时指针一起移动。 代码如下 class Solution { public ListNode getKthFromEnd(Lis原创 2022-03-14 11:05:18 · 926 阅读 · 0 评论 -
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。 示例: 输入:nums = [1,2,3,4] 输出:[1,3,2,4] 注:[3,1,2,4] 也是正确的答案之一。 题解 这题太让我恶心了。 核心是循环交换的思想,难点是交换的条件以及跳出本次循环的条件。 首先想到用两个指针来标记奇数和偶数的位置。 i 下标代表搜索 奇数的下标,从 0 开始 j 下标代表搜索 偶数的下标,从最后一个数据开始 只要两个指针没有相遇,进入循环 如果 i 下原创 2022-04-01 14:56:07 · 539 阅读 · 0 评论 -
剑指 Offer 18. 删除链表的节点
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。 返回删除后的链表的头节点。 注意:此题对比原题有改动 示例 1: 输入: head = [4,5,1,9], val = 5 输出: [4,1,9] 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9. 题解 为了防止前一个节点(preNode)发生空指针异常,所以这里对头结点进行单独判断 对剩余节点进行循环判断 class Solution { publ原创 2022-04-01 11:00:01 · 493 阅读 · 0 评论 -
剑指 Offer 17. 打印从1到最大的n位数
输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。 示例 1: 输入: n = 1 输出: [1,2,3,4,5,6,7,8,9] 题解 本题可以翻译成怎么使输入的整数 n 代表位数 对输入的 n 从 1 开始循环,每一次循环将 num *10 将局部数组变量大小初始化为 num-1 最后遍历给数组赋值即可 class Solution { public int[] printNumbers(int n)原创 2022-04-01 10:20:58 · 142 阅读 · 0 评论 -
剑指 Offer 11. 旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为 1。 注意,数组 [a[0], a[1], a[2], …, a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], …, a[n-2]] 。 示例 1: 输入:number原创 2022-03-31 22:17:05 · 211 阅读 · 1 评论 -
剑指 Offer 10- II. 青蛙跳台阶问题
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1: 输入:n = 2 输出:2 解释:有两种方法可以爬到楼顶。 1 阶 + 1 阶 2 阶 示例 2: 输入:n = 3 输出:3 解释:有三种方法可以爬到楼顶。 3. 1 阶 + 1 阶 + 1 阶 4. 1 阶 + 2 阶 5. 2 阶 + 1 阶 思路: 题目很明显是一个递归问题,可以将整体问题划分为多个小问题: 我们先假设楼梯只有一阶,也就是 n 为1;此时只有一种办法原创 2022-03-10 13:25:23 · 278 阅读 · 0 评论 -
剑指 Offer 10- I. 斐波那契数列
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下: F(0) = 0, F(1) = 1 F(N) = F(N - 1) + F(N - 2), 其中 N > 1. 斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。 答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。 示例 1: 输入:n = 2 输出:1 示例 2: 输入:n = 5 输出:5 解题思路原创 2022-03-10 13:44:05 · 107 阅读 · 0 评论 -
剑指 Offer 09. 用两个栈实现队列&leetcode232.用栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(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, siz原创 2022-03-14 11:56:28 · 148 阅读 · 0 评论 -
剑指 Offer 06. 从尾到头打印链表
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 题解 我首先想到的是反转链表,然后将反转的链表的值循环赋值给数组。 后来出现了空指针异常的问题。 问题是因为没有对创建的数组进行初始化大小设置。 public int[] reversePrint(ListNode head) { if(head == null){ return null; }原创 2022-03-30 19:50:06 · 1295 阅读 · 0 评论 -
剑指 Offer 24. 反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1] 解题思路 关键在于指针移动的顺序 与 节点之间绑定的先后顺序。 先获取头结点的下一个节点的引用 再更改头结点指向的下一个节点的引用 再移动 preNode 指针 最后移动头结点的引用指针 返回 preNode 节点 代码如下 class Solution { public ListNode reverseList(ListNode head原创 2022-03-11 14:02:17 · 129 阅读 · 0 评论 -
剑指 Offer 05. 替换空格
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。 示例 1: 输入:s = “We are happy.” 输出:“We%20are%20happy.” 题解 首先想到用替换函数 replace(" “,”%20"); 将原字符串进行替换 用字符串的 replaceAll 函数也可以,但是效率没有 replace 好 不使用函数,使用StringBuilder 创建stringBuilder对象str 将遍历的单个字符赋值给 ch 接着判断该字符是不是为空格 如果是空格,就在str后面原创 2022-03-30 16:05:52 · 318 阅读 · 0 评论 -
剑指 Offer 03. 数组中重复的数字
题目介绍 找出数组中重复的数字。 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。 示例 1: 输入: [2, 3, 1, 0, 2, 5, 3] 输出:2 或 3 题解 题目可以翻译成找出一个数组中第一个重复的数据 选择容器,由于只是找出数组中的重复值,不涉及下标,选择Map和Set中的Set 遍历数组,同时判断该数据是否能添加到(add)Set中 如果不能添.原创 2022-03-30 14:33:56 · 321 阅读 · 0 评论