当前位置:网站首页>剑指offer-高质量的代码
剑指offer-高质量的代码
2022-07-07 02:23:00 【Nefelibat】
在博客上记录算法笔记,是因为想push自己每天坚持刷几道算法题,同时也希望能把自己总结到的经验分享给大家,希望大家阅读愉快
目录
注意:应聘者在写代码的时候,最好用完整的英文单词组合命名变量和函数。
如果要删除的节点位于链表的尾部,遍历链表得到这个节点的前序节点,那么就不存在下一个节点, 如果链表中只有 一个节点,那么在删除节点之后将链表的头节点设置为nullptr.
面试官常常考虑的
从程序的正确性和鲁棒性两方面检验代码的质量,比如输出参数的检测,处理错误和异常的方式,命名方式。
代码的规范性
注意:应聘者在写代码的时候,最好用完整的英文单词组合命名变量和函数。
代码的完整性
检查代码是否完成基本的功能,输入的边界值是否能得到正确的输出、对各种用例就做出了处理。
题目:数值的整数次方
用手写代码实现C语言中的pow()函数。
思路
需要考虑指数小于1的情况。当指数为负数,先对指数取绝对值,算出结果之后再取倒数。但是当底数是0的时候取倒数会报错,需要进行特殊处理,同样0的0次方在数学上是没有意义的,因此取0和取1都是可以接收的。
代码
全面高效的代码
如果指数比较大的化,需要做31次乘法,求一个数的32次方,如果已经知道了它的的16次方,那么只要在16次方的基础上再平方一次就可以,这样的化32次方我们需要做5次乘法。
我们用右移代替了除2,位运算的效率比较高
题目:打印从1到最大的n位数
输入数字n,按顺序从1到最大的n位十进制数,比如输入3,则打印出1,2,3,...999
思路
最容易想到的是先求出最大的n位数,然后循环从1开始打印,代码如下:
代码
但是当输入n很大的时候,是不是会溢出?
思路
在字符串上模拟数字加法的解法,可以用字符串表示大数。字符串表示数字的时候,字符串中的每个字符都是0-9之间的某一个字符,用来表示数字中的一位。因为数字最大是n位,我们需要一个长度为n+1的字符串,字符串中的最后一位是结束符号\0,当实际数字不够n位的时候,在字符串的前半部分补0. Increment表示数字的字符串number上增加1,PrintNumber打印出number,
我们需要最大什么时候停止在number增加1,在每次递增之后,调用strcmp()表示数字的字符串number和最大的n位数“99...99”,只有在“99..99”加1的时候,才会在第一个字符的基础上产生进位,
代码
将问题转换成数字排列的问题,递归让代码更简洁
测试用例
1、功能测试,输入1,2,3,..
2、特殊输入测试,输入-1,0
扩展
在前面的代码。我们用char的一个字符表示十进制数中的一位,8bit的字符最多能表256个字符,2的8次方,但是十进制的数字0-9只能表示10个数字,因为char字符能充分利用内存,那么有没有更高效的表示大数?
题目:删除链表的节点
在o(1)时间内删除节点,跟定一个单链表的头指针和一个节点指针。
思路
遍历链表找到需要删除的节点,并从链表中删除节点。
存在问题:
如果要删除的节点位于链表的尾部,遍历链表得到这个节点的前序节点,那么就不存在下一个节点, 如果链表中只有 一个节点,那么在删除节点之后将链表的头节点设置为nullptr.
代码
用例
删除头节点,删除尾节点,删除只有一个节点的链表
题目:删除链表中重复的节点
在一个排序的链表中,如何删除重复的节点
思路
从头遍历链表,如果当前节点与下一个节点的值相同,就删除
代码(后续需要看)
用例
重复的节点位于链表的头部、尾部,中间,链表中没有重复的节点,指向链表头节点的是nullptr指针,链表中的所有节点都是重复的。
题目:正则表达式匹配
设置一个函数用来匹配包含“.”和“*”的正则表达式,模式中的“.”可以表示任意一个字符,“*”表示它前面的字符可以出现任意次,例如,“aaa”与“a.a”和“ab*ac*a”匹配。
思路
当模式中第二个字符不是“*”时,如果字符串中的第一个字符和模式中的第一个字符相匹配,那么字符和模式都向后移动一个字符,然后匹配剩余的字符串和模式,如果字符串中的第一个字符和模式中的第一个字符不匹配,返回false.
当模式中的第二个字符是“*”时,模式上向后移动两个字符,相当于“*”和它前面的字符被忽略,
代码
用例
字符串和模式字符串是nullptr或者空字符串,模式字符串汇总包含“.”和“*”,模式字符串和输入字符串匹配或者不匹配
题目:表示数值的字符串
实现用一个函数判断字符串是否表示数值
例如“12e“,"1a3.14"不是数值
思路
用A,B, C 三部分分别代码数值的整数、小数和指数部分,首先扫描数值的整数部分,如果遇到“.”,扫描数值的小数部分,如果遇到e或者E,扫描数值的指数部分。
代码
用例
正数、负数、包含不包含整数部分的数值,包含不包含小数部分的数值,包含不包含指数部分的数值;输入字符串或者模式字符串是nullptr,空字符串。
题目:调整数组顺序使奇数位于偶数前面
思路
如果不考虑时间问题,从头扫描这个数字,每碰到一个偶数,拿出这个数字,将位于这个数字后面的数字往前挪动一位,数字末尾空出一个空位,将该偶数放入这个空位,移动一次的时间复杂度是o(n),因此时间复杂度是o(n2)
改进思路
在扫描数组的时候发现偶数出现在奇数的前面,交换两个数字,用一个指针指向数组的第一个数字,往后移动,一个指针指向数组的最后一个数字,往前移动,如果前面的指针指向的是偶数,并且第二个指针指向的是奇数,交换两个数字。
代码
扩展题目:将一个数组中的负数放在非负数的前面
扩展题目:将一个数组能被3整除的数放在不能被3整除的数前面
为了解决这一类问题,只需要修改判断条件,因此可以将这个逻辑框架抽象出来,用一个单独的函数用来判断数字是否符合标准。
代码
用例
数组中的偶数和奇数交替出现,输入的所有数组都出现在奇数的前面,输入的所有的奇数都出现在偶数的前面,输入nullptr指针,数组只包含一个数字
题目:链表中的倒数第K个节点
思路
1、先遍历到链表的尾端,然后回溯k步,但是单向链表没有前向指针
2、从头开始遍历链表,链表有n个节点,那么倒数第K个节点即使从头节点开始的n-K+1个节点
3、第二种方法需要遍历链表2次,如果面试官要求遍历链表1次,那么第二种方法不可行,需要两个指针,第一个指针从头开始遍历k-1个节点时,第二个指针从链表的头节点开始遍历,这样两个指针的距离就是k-1,当第一个指针到达尾部时,第二个指针指向链表的第K个节点。
代码
存在的问题
如果输入的头节点指向的是空指针,输入的链表的节点数小于k,输入的k是0,针对这三个问题分别处理。
改进代码
用例
第 k个节点是链表的头节点,尾节点;链表的头节点是nullptr,链表的总节点数小于k,k等于0.
题目:链表中的环的入口节点
思路
第一步确定链表中是否含有环,定义两个指针,同时从链表的头节点出发,一个指针一次走一步,另一个指针一次走两步,如果两个指针相遇,那么链表就有环,如果一个指针到了链表的末尾,那么就不包含环。
第二步是找到环的入口,假设一个链表包含n个节点,一个指针先走n步,然后另一个指针从头指针出发,一个指针从尾部出发,两个指针相遇的节点就是入口节点。然后从这个节点开始计数,再次回到这个节点计数结束。
代码
用例
链表中包含环或者不包含环,链表中有多个或者只有一个节点,链表头节点为nullptr指针
题目:反转链表
思路
在我们调节节点i的时候,需要知道节点i的前一个节点h,我们将 i的next指针指向h
代码
用例
链表中有多个节点,链表中有一个节点,链表头节点为nullptr指针
题目:合并两个排序的链表
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
思路
1、链表1的头节点小于链表2的头结点的值,因此链表1的头节点是合并后链表的头节点。
2、在剩余的节点中,链表2的头结点小于链表1的头结点,因此链表2的头结点是剩余节点的头节点
因为合并的步骤都是一样的,因此这可以看做是一个递归过程。
代码
用例
待合并的两个链表有多个节点;节点的值互不相同或者存在值相等的多个节点;两个链表汇总只有一个节点;两个链表的头指针是nullptr.
题目:树的子结构(和链表相比,树的指针更难)
输入两棵二叉树A和B,判断B是不是A的子结构。
思路
第一步,在A 中找到和B的根节点一样的节点R,第二步,判断A中以R为根节点的子树是不是包含和B一样的结构。
代码
第一步需要遍历树,树的遍历可以递归,可以循环,递归的方法较简单。
用例
A和B是普通的二叉树,B不是A的子结构,A和B的一个或者两个根节点为nullptr指针,A 或B没有左指数或者右指数。
注意
1、在每次使用指针的时候,我们都要问自己这个指针有没有可能是nullptr,如果是nullptr应该怎么处理。
2、由于计算机表示小数有误差,我们不能直接使用符号==判断两个小数是否相等,如果两个小数的差的绝对值很小,就可以认为相等。
边栏推荐
- c语言面试写一个函数在字符串N中查找第一次出现子串M的位置。
- Cloudcompare point pair selection
- A program lets you understand what static inner classes, local inner classes, and anonymous inner classes are
- How to use wechat cloud hosting or cloud functions for cloud development of unapp development applet
- Problems and precautions about using data pumps (expdp, impdp) to export and import large capacity tables in Oracle migration
- Basic DOS commands
- Stack and queue-p78-8 [2011 unified examination true question]
- 哈趣投影黑馬之姿,僅用半年强勢突圍千元投影儀市場!
- Abnova循环肿瘤DNA丨全血分离,基因组DNA萃取分析
- UIC (configuration UI Engineering) public file library adds 7 industry materials
猜你喜欢
Redhat5 installing vmware tools under virtual machine
Go straight to the 2022ecdc fluorite cloud Developer Conference: work with thousands of industries to accelerate intelligent upgrading
MySQL installation
MySQL的安装
程序员的日常 | 每日趣闻
"Parse" focalloss to solve the problem of data imbalance
How to install swoole under window
屏幕程序用串口无法调试情况
Pinduoduo lost the lawsuit: "bargain for free" infringed the right to know but did not constitute fraud, and was sentenced to pay 400 yuan
LM小型可编程控制器软件(基于CoDeSys)笔记二十三:伺服电机运行(步进电机)相对坐标转换为绝对坐标
随机推荐
uniapp开发小程序如何使用微信云托管或云函数进行云开发
程序员的日常 | 每日趣闻
Postgresql源码(59)分析事务ID分配、溢出判断方法
Redhat5 installing vmware tools under virtual machine
"Parse" focalloss to solve the problem of data imbalance
Force deduction 62 different paths (the number of all paths from the upper left to the lower right of the matrix) (dynamic planning)
2022Android面试必备知识点,一文全面总结
Ant manor safety helmet 7.8 ant manor answer
ETCD数据库源码分析——从raftNode的start函数说起
How can I check the DOI number of a foreign document?
Basic DOS commands
PostgreSQL database timescaledb function time_ bucket_ Gapfill() error resolution and license replacement
tkinter窗口选择pcd文件并显示点云(open3d)
Stack and queue-p78-8 [2011 unified examination true question]
Party A's requirements for those who have lost 800 yuan
Abnova 体外转录 mRNA工作流程和加帽方法介绍
谷歌 Chrome 浏览器发布 103.0.5060.114 补丁修复 0-day 漏洞
Leite smart home longhaiqi: from professional dimming to full house intelligence, 20 years of focus on professional achievements
拼多多败诉:“砍价免费拿”侵犯知情权但不构成欺诈,被判赔400元
Installing redis and windows extension method under win system