【剑指 Offer】(1)
文章目录
- 前言
- 一、 数组中重复的数字
- :fire: 解决方法
- :dog: 代码
- 二、二维数组中的查找
- :fire:思路
- :dog:代码
- 三、替换空格
- :fire:思路
- :dog: 代码
- 四、从尾到头打印链表
- :fire:思路
- :dog:代码
- :dog: 代码
- 五、重建二叉树
- :fire:思路
- :dog: 代码
- 总结
前言
剑指offer系列是一本非常著名的面试题目集,旨在帮助求职者提升编程能力和应对面试的能力
。随着互联网行业的迅速发展和竞争的加剧,技术人才的需求量也越来越大,而面试已经成为求职过程中至关重要的一环。 剑指offer系列汇集了许多公司常见的面试题目,并且针对每个问题都给出了详细的解答和分析,对于准备参加面试的求职者来说非常实用。
在本系列文章中,我们将一步步地学习这些问题的解决方法,掌握如何在面试中优雅地回答这些问题,帮助读者更好地备战面试,拿到心仪的工作机会❤️。
一、 数组中重复的数字
找出数组中重复的数字
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
🔥 解决方法
该方法将整数数组作为输入,并返回找到的第一个重复数字。使用的算法基于将元素交换到其相应的索引位置的想法,直到找到重复的元素。
该算法的工作原理如下:
1️⃣.初始化指向0的指针.
2️⃣.虽然小于数组的长度:
- 🅰️.如果索引处的当前元素已经等于,则递增并继续到下一个元素。
- 🅱️.如果索引处的值给出的索引处的元素等于索引处的值,那么我们找到了一个重复的数字,所以返回这个数字。
- ❌.否则,将索引处的元素与其值给定的索引处的元素交换。
3️⃣.如果未找到重复元素,则返回-1。
总体而言,该算法的时间复杂度为0(),因为它扁历整个数组一次。空间复杂度为O(1),因为它不使用任何其他数据结构来存储有关数组的信息。
🐶 代码
class Solution {public int findRepeatNumber(int[] nums) {// 将指针i初始化为0int i=0;// 当"i"小于数组的长度时:while(i<nums.length){// 如果当前元素在索引“i”处已经等于“i”,则增加“i”并继续到下一个元素。if(nums[i]==i){i++;continue;} // 如果索引i处的值给出的索引处的元素等于索引i处的值,那么我们找到了一个重复的数字,因此返回该数字。if(nums[nums[i]]==nums[i])return nums[i];// 否则,将下标为“i”的元素与下标为其值的元素交换。.int t =nums[i];nums[i]=nums[t];nums[t]=t;}// 如果没有找到重复的元素,则返回-1。return -1;}
}
总体来说,这段代码实现了在整型数组中查找第一个重复数字的功能。该算法的时间复杂度为O(n),空间复杂度为O(1)。
二、二维数组中的查找
二维数组中的查找
在一个 n * m 的二维数组中,每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例:
现有矩阵 matrix 如下:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
限制:
0 <= n <= 1000
0 <= m <= 1000
🔥思路
这段代码定义了一个名为 Solution 的类,其中包含一个名为 findNumberIn2DArray 的方法。
1️⃣. 该方法接收两个参数:一个二维整数数组 matrix 和一个整数 target。目标是在二维数组中查找是否存在目标整数。
2️⃣该方法使用 while 循环从左下角开始遍历 matrix。
- 如果当前元素大于 target,则将行索引减少;
- 如果当前元素小于 target,则将列索引增加。如果当前元素等于 target,则返回 true。
- 如果 while 循环完成后仍未找到 target,则返回 false。
总体而言,这个算法被称为“在二维矩阵中搜索”问题,可以使用二分搜索或双指针方法进行解决,因为矩阵是有序的。
需要注意的是,此实现假定 matrix 按行和列均按非降序排列。
🐶代码
class Solution {public boolean findNumberIn2DArray(int[][] matrix, int target) {// 初始化行和列索引,从左下角开始遍历int rows = matrix.length - 1, col = 0;while(rows >= 0 && col < matrix[0].length){// 如果当前元素比目标大,则将行索引减少if(matrix[rows][col] > target) rows--;// 如果当前元素比目标小,则将列索引增加else if(matrix[rows][col] < target) col++;// 如果当前元素等于目标,返回 trueelse return true;}// 循环结束后仍未找到目标,返回 falsereturn false;}
}
三、替换空格
替换空格
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1:
输入:s = “We are happy.”
输出:“We%20are%20happy.”
限制:
0 <= s 的长度 <= 10000
🔥思路
这段Java代码定义了一个名为Solution的类,其中包含了一个replaceSpace方法。
- 该方法接收一个字符串s作为输入,并返回将字符串中所有空格替换成"%20"之后得到的修改后 的新字符串。在实现中,该方法使用了一个StringBuilder对象来逐个构建新字符串。
- 它遍历输入字符串中的每个字符,判断当前字符是否为空格。如果是,则向StringBuilder对象中添加"%20";
- 否则,向StringBuilder对象中添加原始字符。
这段代码似乎是解决一个常见的编程问题,即将字符串中的空格替换为"%20"。在处理URL或其他类型的Web资源时,经常遇到这种问题。
🐶 代码
class Solution {public String replaceSpace(String s) {StringBuilder bulider = new StringBuilder(); // 创建一个StringBuilder对象用于构建新字符串for(int i = 0 ; i <s.length();i++){ // 遍历输入字符串中的每个字符if(s.charAt(i)==' ') // 如果当前字符是空格bulider.append("%20"); // 向StringBuilder对象中添加"%20"else // 如果当前字符不是空格bulider.append(s.charAt(i)); // 向StringBuilder对象中添加原始字符}return bulider.toString(); // 返回由StringBuilder对象构建的新字符串}
}
四、从尾到头打印链表
从尾到头打印链表
🔥思路
🅰️ 方式一
Java算法流程:
1️⃣. 递推阶段:每次传入head.next,以head=null (即走过链表尾部节点) 为递归终止条件,此时直接返回。
2️⃣. 回溯阶段:层层回时,将当前节点值加入列表,即tmp.add(head.val)。
3️⃣. 最终,将列表tmp转化为数组 res,并返回即可。
- 时间复杂度O(N): 遍历链表,递归N次。
- 空间复杂度O(N): 系统递归需要使用O(N)的栈空间。
该解决方案计算链表的长度,并使用一个数组来存储链表元素。我们首先遍历链表以计算其长度。然后创建一个大小为链表长度的数组,并从头到尾遍历链表,将每个节点的值存储在数组中。
最后,返回结果数组,其中包含链表元素的倒序副本。
❤️请注意,这两种方法的时间复杂度均为O(n),其中n是链表的长度。
🐶代码
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/
class Solution {public int[] reversePrint(ListNode head) { // 计算链表长度ListNode cur = head;int len = 0;while(cur!=null){cur = cur.next;len++;}// 创建结果数组,并将链表元素倒序存入其中int[] res =new int[len];ListNode node = head;int i = len-1;while(node!=null){res[i]=node.val;i--;node = node.next;}// 返回结果数组return res;}
}
🅱️ 方式二
1️⃣. 入栈:遍历链表,将各节点值push入栈。(Python使用append()方法,Java借助
LinkedList的addLast)方法)。
2️⃣ 出栈:将各节点值pop出栈,存储于数组并返回。(Python直接返回stack的倒序列表,
Java新建一个数组,通过popLast() 方法将各元素存入数组,实现倒序输出)。
这是一个用于反转和打印链表内容的 Java 解决方案。它首先创建一个堆栈并遍历链表,将每个节点的值推送到堆栈上。将所有节点添加到堆栈后,它会使用堆栈的大小初始化整数数组,然后将堆栈中的值弹出到整数数组中,从而创建相反的顺序。LinkedList
该类不包含在提供的代码片段中,但它可能是程序中其他位置使用的自定义类。ListNode
🐶 代码
class Solution {public int[] reversePrint(ListNode head) {// 创建一个新的LinkedList作为堆栈LinkedList<Integer> stack = new LinkedList<Integer>();//遍历链表,将每个节点的值添加到堆栈中while(head != null) {stack.addLast(head.val);head = head.next;}// 创建一个与堆栈大小相同的整数数组int[] res = new int[stack.size()];// 将值从堆栈中弹出到整数数组中,反转它们的顺序for(int i = 0; i < res.length; i++)res[i] = stack.removeLast();// 返回反转的整数数组return res;}
}
五、重建二叉树
重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
示例 2:
Input: preorder = [-1], inorder = [-1]
Output: [-1]
限制:
0 <= 节点个数 <= 5000
🔥思路
这是一个 Java 代码,实现了从二叉树的预序和无序遍历数组构造二叉树的解决方案。这里使用的方法本质上是递归的。
1️⃣该方法采用两个输入数组:表示二叉树的预序遍历,以及表示同一二叉树的无序遍历。该方法初始化一个命名以存储数组中每个元素的索引。buildTree, preorder, inorder ,HashMapIndex ,HashMap ,inorder。
- 在该方法中,检查的第一件事是 or 数组是否为空。
- 如果为 true,则返回 null,因为没有更多要处理的元素。treeBuilder ,preorder,inorder
如果没有,它将检索数组的第一个元素,该元素应该是二叉树的当前根节点。将使用该值创建一个新值。preorder,TreeNode
该变量使用从 .preIndex,inorder,get(),IndexHashMap
2️⃣接下来,通过使用更新的参数调用方法,递归构造左侧子树。
数组中左子树的起始索引是通过在 上加 1 并从计算中减去来给出的。数组中左侧子树的结束索引位于 。treeBuilder,preorder,preLeft,inLeft,preIndex,inorder,preIndex - 1
右子树的构造类似,但数组中的起始索引是通过添加到 来计算的,而数组中的结束索引位于 。preorder,preIndex - inLeft + 1,preLeft,inorder,inRigth
❌最后,返回表示子树根节点的构造。TreeNode
总体而言,该算法的时间复杂度为 O(n),其中 n 是树中的节点数,因为它访问每个节点一次。
🐶 代码
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val = x; }* }*/// 定义 Solution 类
class Solution {private Map<Integer,Integer> IndexHashMap; // 声明一个 Hashmap 存储中序遍历数组元素及其下标public TreeNode buildTree(int[] preorder, int[] inorder) { // 构建二叉树的方法,输入是前序和中序遍历数组IndexHashMap = new HashMap(); // 初始化上文声明的 HashMapfor(int i =0 ;i<inorder.length;i++){ // 遍历中序遍历数组IndexHashMap.put(inorder[i],i); // 将中序遍历数组的元素及其下标存入 HashMap 中}// 调用递归方法构建二叉树并返回根节点return treeBuilder(preorder,0,preorder.length-1,inorder,0,inorder.length-1);}// 递归函数,用于构建一棵子树private TreeNode treeBuilder(int[] preorder,int preLeft,int preRight,int[] inorder,int inLeft,int inRigth){// 如果传进来的数组为空,则返回 nullif(preLeft>preRight || inLeft>inRigth) return null;// 取出当前子树的根节点,并创建新节点int rootValue = preorder[preLeft];TreeNode root = new TreeNode(rootValue);// 获取当前根节点在中序遍历数组中的下标int preIndex=IndexHashMap.get(rootValue);// 递归构建左子树root.left = treeBuilder(preorder,preLeft+1,preIndex+preLeft-inLeft,inorder,inLeft,preIndex-1);// 递归构建右子树root.right = treeBuilder(preorder,preIndex+preLeft-inLeft+1,preRight,inorder,preIndex+1,inRigth);// 返回当前根节点return root;}
}
总结
提示:这里对文章进行总结:
以上五道算法题是典型的面试题,还有很多各种类型的算法题,接下来回继续更新,持续更新🔥🔥🔥。
相关文章:

【剑指 Offer】(1)
文章目录前言一、 数组中重复的数字:fire: 解决方法:dog: 代码二、二维数组中的查找:fire:思路:dog:代码三、替换空格:fire:思路:dog: 代码四、从尾到头打印链表:fire:思路:dog:代码:dog: 代码五、重建二叉树:fire:思路:dog: 代码总结前言 剑指offer系列是一本非常著名的面试题…...

每日一题 leetcode1026 2023-4-18
1026. 节点与其祖先之间的最大差值 力扣题目链接 给定二叉树的根节点 root,找出存在于 不同 节点 A 和 B 之间的最大值 V,其中 V |A.val - B.val|,且 A 是 B 的祖先。 (如果 A 的任何子节点之一为 B,或者 A 的任何…...

【Python_Scrapy学习笔记(十二)】基于Scrapy框架实现POST请求爬虫
基于Scrapy框架实现POST请求爬虫 前言 本文中介绍 如何基于 Scrapy 框架实现 POST 请求爬虫,并以抓取指定城市的 KFC 门店信息为例进行展示 正文 1、Scrapy框架处理POST请求方法 Scrapy框架 提供了 FormRequest() 方法来发送 POST 请求; FormReques…...

《花雕学AI》02:人工智能挺麻利,十分钟就为我写了一篇长长的故事
ChatGPT最近火爆全网,上线短短两个多月,活跃用户就过亿了,刷新了历史最火应用记录,网上几乎每天也都是ChatGPT各种消息。国内用户由于无法直接访问ChatGPT,所以大部分用户都无缘体验。不过呢,前段时间微软正…...

做程序员累了想要转行?我想给大家分享一下看法
今天早上起床时,我看到有粉丝评论说关于程序员的话题,如果做着觉得累了,就会觉得自己不适合这个工作,想转行。我想给大家分享一下我的看法。 在我刚开始工作时,有人说我不适合做这个工作,但是我坚持了下来…...

如果你想从事人工智能职业,学习Python吧
人工智能并不会抢走你的工作,至少目前还不会。人工智能和机器学习(AI/ML)最好的应用是补充人类的创造力,而不是取代它。具有讽刺意味的是,最好的大型语言模型(LLMs)可能是通过使用受版权保护的人…...

百模大战,谁是下一个ChatGPT?
“不敢下手,现在中国还没跑出来一家绝对有优势的大模型,上层应用没法投,担心押错宝。”投资人Jucy(化名)向光锥智能表示,AI项目看得多、投的少是这段时间的VC常态。 ChatGPT点燃AI大爆炸2个月中࿰…...

Revit中怎么绘制多面坡度的屋顶及生成墙
一、Revit中怎么绘制多面坡度的屋顶 像这种坡屋顶我们可以观察到,它的屋顶轮廓都是带有坡度的,那我可以通过添加定义坡度的方式来绘制出该屋顶。 点击建筑选项卡中的屋顶按钮,选择迹线屋顶。 选择使用拾取线工具,在选项栏中将偏…...

【jvm系列-07】深入理解执行引擎,解释器、JIT即时编译器
JVM系列整体栏目 内容链接地址【一】初识虚拟机与java虚拟机https://blog.csdn.net/zhenghuishengq/article/details/129544460【二】jvm的类加载子系统以及jclasslib的基本使用https://blog.csdn.net/zhenghuishengq/article/details/129610963【三】运行时私有区域之虚拟机栈…...

【GCU体验】基于PaddlePaddle + GCU跑通模型并测试GCU性能
一、环境 地址:启智社区:https://openi.pcl.ac.cn/ 二、计算卡介绍 云燧T20是基于邃思2.0芯片打造的面向数据中心的第二代人工智能训练加速卡,具有模型覆盖面广、性能强、软件生态开放等特点,可支持多种人工智能训练场景。同时具备灵活的可…...

解析hash(散列)数据结构
前言 在学习完map、set这两个由红黑树构成的容器后,我们来到了这里hash,首先我们要有一个基础的认知——哈希和map与set的仅在使用时的差别区别:前者内部的元素没有序,而后者有序,其它的都相同,这里我们可…...

《2023金融科技·校园招聘白皮书》新鲜出炉|牛客独家
数智创新时代,科技人才为先。 眼下,在建设“数字中国”的时代背景下,金融行业全面数智化转型已箭在弦上。政策端,金融行业为中共中央、国务院印发《数字中国建设整体布局规划》的7大重点行业之一。 资本端,仅2022年三…...

文明的标志:书写系统、修建城市、使用金属器
文章目录 引言I 预备知识1.1 文明”和“文化”概念1.2 文明的标志1.3 应对水患II 定居开启了人类文明2.1 书写系统2.2 陶器2.3 家畜引言 一切和开启文明相关的技术都是围绕着两根主线展开: 多获取能量,以便于生存,信息能够管理起酋邦,总结、记录并传授经验。I 预备知识 1.…...

算法:将一个数组旋转k步
题目 输入一个数组如 [1,2,3,4,5,6,7],输出旋转 k 步后的数组。 旋转 1 步:就是把尾部的 7 放在数组头部前面,也就是 [7,1,2,3,4,5,6]旋转 2 步:就是把尾部的 6 放在数组头部前面,也就是 [6,7,1,2,3,4,5]… 思路 思…...

使用大华惠智双目半球网络摄像机DH-IPC-HD4140X-E2获取人流量统计数据
记录一下使用Java的SpringBoot大华SDK在智慧公厕项目中使大华惠智双目半球网络摄像机DH-IPC-HD4140X-E2获取人流量统计数据 首先根据说明书登录摄像头,一般摄像头都有自己的账号和密码(可能是admin admin 也可能是admin 888888 还有可能是admin 12345),…...

DC插装式流量阀压力阀
Cartridge Valves 电磁阀 止回阀 运动控制阀 流量控制阀 溢流阀 压力控制阀 顺序阀 梭阀 方向阀 配件 Zero Profile Valves 止回阀 运动控制阀 流量控制阀 溢流阀 梭阀 In-Line Valves 止回阀和梭阀 方向阀 配件 微型系列 AB20S APIDC-30S C10B C10S C10S…...

NumPy 数组学习手册:6~7
原文:Learning NumPy Array 协议:CC BY-NC-SA 4.0 译者:飞龙 六、性能分析,调试和测试 分析,调试和测试是开发过程的组成部分。 您可能熟悉单元测试的概念。 单元测试是程序员编写的用于测试其代码的自动测试。 例如&…...

【笔试强训选择题】Day6.习题(错题)解析
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、Day6习题(错题)解析 二、Day6习题(原题)练习 总结 前言 一、Day6习题(错题)解析…...

磁盘分区-LINUX
1、主分区(primary) 磁盘在Linux当中的命名: IDE /dev/hda hdb SCSI sda sdb 分区数字表示:sda1 、sda2、sda3 磁盘分区相当于给磁盘打隔断 ① 系统中必须要存在的分区,系统盘选择主分区安装 ② 数字编号只能是1-4&am…...

SpringAOP入门基础银行转账实例(进阶版)------------事务处理
SpringAOP入门基础银行转账实例**(进阶版)**------------事务处理 由上一节讲述的通过Connection和QueryRunner对事务进行的处理(详情可以去我之前写的博客文章:https://blog.csdn.net/m0_56245143/article/details/130069160?spm1001.2014…...

【python学习】基础篇-常用函数-format函数 格式化操作
format()可以对数据进行格式化处理操作,语法如下: format(value,format_spec) value 为要转换的数据,fommat spec 为格式化解释, 当参数 format spec 为空时,等同于函数 str(value)的方式。 format spec 可以设置非常复…...

团团面试经验
1、Redis同时访问大量不存在的key会发生什么? 如果是缓存和数据库中都不存在,那么就会发生缓存穿透。 举个例子:某个黑客故意制造一些非法的 key 发起大量请求,导致大量请求落到数据库,结果数据库上也没有查到对应的数…...

今天面了个京东拿 38K 出来的,让我见识到了基础的天花板
今年的春招已经开始了,很多小伙伴收获不错,拿到了心仪的 offer。 各大论坛和社区里也看见不少小伙伴慷慨地分享了常见的软件测试面试题和八股文,为此咱这里也统一做一次大整理和大归类,这也算是划重点了。 俗话说得好࿰…...

Qt创建SDK库(dll动态库)并调用SDK库(dll动态库)
Qt创建SDK库(dll动态库)并调用SDK库(dll动态库) 一、项目场景 在日常的项目中,我们经常会遇到调用别人的数学库、线程库、图形库等操作。这些库通常就被称为SDK,SDK全称是Software Development Kit(软件开发工具包),…...

400以内的蓝牙耳机哪款好?400以内蓝牙耳机排行榜
谈起TWS,无论是传统的音频厂商还是手机厂商,都是其不可或缺的重要产品线,现在很多许多蓝牙耳机都不是千篇一律得形状,市场也鲜有商家在外观上下功夫,下面分享几款400元以内,内外兼具的耳机品牌。 一、南卡…...

基于飞桨实现的特定领域知识图谱融合方案:ERNIE-Gram文本匹配算法
文本匹配任务在自然语言处理领域中是非常重要的基础任务,一般用于研究两段文本之间的关系。文本匹配任务存在很多应用场景,如信息检索、问答系统、智能对话、文本鉴别、智能推荐、文本数据去重、文本相似度计算、自然语言推理、问答系统、信息检索等&…...

前端基础复习
1.什么叫HTML5?和原本的所说的HTML有什么区别? 本质上html和html5是一样的的。区别有: 1. 在文档类型声明上 HTML4.0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loos…...

Vue2 API-源码解析
目录 Vue.extend(option) delimiters functional Vue.component(id, Function | Object) Vue.directive( id, [definition] ) Vue.filter( id, function) Vue.nextTick() Vue.set() Vue.delete(target, index/key) Vue.compile(template) Vue.observable(object) …...

FastViT: A Fast Hybrid Vision Transformer using Structural Reparameterization
FastViT: A Fast Hybrid Vision Transformer using Structural Reparameterization 论文地址:https://arxiv.org/pdf/2303.14189.pdf 概述 本文提出了一种通用的 CNN 和 Transformer 混合的视觉基础模型 移动设备和 ImageNet 数据集上的精度相同的前提下…...

C/C++文档阅读笔记-A Simple Makefile Tutorial解析
Makefile文件可以使得程序编译变得简单。本博文并不是很系统的讲解makefile,本博文的目标是让读者快速编写自己的makefile文件并能应用到中小项目中。 简单实例 举个例子有下面3个文件,分别是hellomake.c,hellofunc.c,hellomake.…...