剑指OFFER 读书心得 python实现

别人的总结成果,感谢

这个网址是我后来发现的别人很好的总结,感谢
https://blog.csdn.net/u012505432/article/details/52071537

第一章 面试常识

第二章 面试需要的基础知识

2-3数据结构

2-3-1数组 面试题3 Search a number in 2D Matrix

http://blog.csdn.net/u011462357/article/details/79278482(同剑指面试题3)

2-3-2字符串 面试题4 URL替换空格

http://blog.csdn.net/u011462357/article/details/78593652(类似剑指面试题4 替换空格)

2-3-3链表(面试题5 从头到尾打印链表)

2-3-4树 (面试题6 重建二叉树)

2-3-5栈和队列(面试题7 用两个栈实现一个队列)

2-4算法和数据操作

排序和查找是面试中的重点,应随时,完整地能写出 二分查找,归并排序,快速排序的代码
栈比循环形式简单,但效率不如循环高
要能比较冒泡排序,快速排序,归并排序的优劣,空间复杂度,平均时间复杂度和最差时间复杂度

2-4-1查找和排序 面试题8 旋转数组的最小数字

查找不外乎顺序查找,二分查找,哈希表查找和二叉排序树查找。
二分查找要做到信手拈来面试题8寻找一个旋转数组里的最小数字 链接:http://blog.csdn.net/u011462357/article/details/78884084

2-4-2循环和递归 面试题9斐波那契数列 Leetcode70青蛙跳台阶

递归的实现要比循环的实现简单的多,如果面试官没有明确要求,应该尽量使用递归实现。
递归优点:简洁
递归缺点:1。递归由于是函数调用自身,而函数调用是有时间和空间消耗的:每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址及临时变量,而且往栈里压入数据和弹出数据都需要时间。所以递归实现的效率不如循环。
2。递归中有可能很多计算都是重复的,从而对性能带来很大的负面影响。递归的本质是把一个问题分解成两个或多个小问题。如果多个小问题存在相互重叠的部分,那么就存在重复的计算。
3。除了效率之外,可能引起更严重的问题:调用栈溢出。前面分析中提到需要为每一次调用在内存栈中分配空间,而每个进程的栈容量是有限的。当递归调用的层级太多时,就会超出栈的容量,从而导致调用栈溢出。

斐波那契数列的变形:青蛙跳台阶,一次可以跳1级或者2级,问跳上n级台阶有几种方法。解法:http://blog.csdn.net/u011462357/article/details/79252607

斐波那契数列问题有O(logn)的解法,但不是面试官想考察的重点。

2-4-3位运算 面试题10 二进制中1的个数 Leetcode191 Number of 1 bits

位运算只分5种:

位操作 python表达
&
异或 ^
左移 <<
右移 “>>”

可参考 https://www.jianshu.com/p/3a31065a8e58
注意!!!http://www.cnblogs.com/zhengyun_ustc/archive/2009/10/14/shifting.html
python中左移操作是无限位数的,详见上面链接。

左移运算符m《《 n表示把m左移n位。左移n位的时候,最左边的n位将被丢弃,同时在最右边补上n个0。
右移运算符m>>n表示把m右移n位。右移n位的时候,最右边的n位将被丢弃。如果数字是无符号数值,则用0填补左边n位。如果数字是一个有符号数值,则用数字的符号位填补最左边的n位。即:如果数字原先 是正数 在右移之后最左边补n个0;如果数字原先是负数 在右移之后最左边补n个1。

题目:把一个十进制数转换成二进制数,数里面1的个数
错误解法:
这里写图片描述

  • Q:在数学上把(二进制)整数右移一位和把整数除以2是等价的,那是否可以把右移换成除以2?
    除法的效率比位移运算低的多!在实际编程中尽可能用位移运算代替乘除法。
  • Q:以上思路有什么bug?
    0x80000000是十六进制数,转换成十进制是2147483648,转换成二进制是10000000000000000000000000000000
  • 如果把负数0x80000000右移一位,并不是简单地把第1位的1移到第二位变成0x40000000,而是0xC0000000,对应11000000000000000000000000000000,所以如果一直右移下去最后会造成FFFFFFFF对应11111111111111111111111111111111陷入死循环。

    补充知识点:
    先补充一个知识点:计算机在做减法运算时,实际上内部是在做加法运算的。
    右移后空出来的高位数值,有0和1两种形式,要想区分什么时候补0什么时候补1,只要掌握了用二进制数表示负数的方法就可以了。
    二进制数中表示负数值时,一般会把最高位作为符号来使用,因此我们把这个最高位成为符号位。符号位为0表示正数,1表示负数。那么-1用8位二进制数怎么表示呢,很多人会认为是10000001,其实这是错的,二进制表示为11111111。计算机是用“二进制的补数”来表示负数的。补数就是用整数来表示负数,过程就是:取反+1。所谓取反,就是将各数位的0反转成1,1取反为0。大家现在就可以试试-1的8进制表示形式了。详情参见http://www.cnblogs.com/Helius/p/7142535.html
    这里写图片描述

    为什么使用补数后就能正确地表示负数了呢?大家可以再详细的看看上图,有一个位溢出去了,而溢出的那一位数计算机是不进行处理的。
    有一个法则大家必须牢记:”将二进制数的值取反后加1的结果,和原来的值相加,结果为0”这个法则。
    总之,要想结果为0,就必须通过补数来实现。当然,结果不为0的运算同样可以通过使用补数来得到正确的结果,不过,有一点需要注意,当运算结果为负数时,计算结果的值也是以补数的形式来表示的。
    3-5的运算:
    3:00000011
    -5:11111011
    00000011+11111011=11111110,最高位变成了1。这就代表结果为一个负数。那11111110表示的负数是多少呢?负负得正大家都知道,所以通过求解补数的补数,就可知道该值的绝对值。所以11111110,取反后加1后为00000010,十进制就是2。所以结果就是-2。

    Q:想理解为什么左移就直接移不用考虑正负,正数明白,负数左移也不用考虑首位符号位,可以见如下例子:http://blog.csdn.net/yusliao/article/details/39152671
    例如 4 <<2 就是16,二进制就是 00000100 <<00010000
    -4<<2 就是-16 二进制就是 11111100 <<11110000
    Leetcode191 Number of 1 bits 详解: http://blog.csdn.net/u011462357/article/details/79336685

    第三章

    3-1面试官谈代码质量

    3-2代码的规范性

    规范的代码应具备:,合理的命名
    清晰的书写:在面试过程中减慢写字的速度,把每个字母清晰地写出来是很有必要
    清晰的布局:对齐、括号匹配、缩进
    合理的命名:写代码时候应用完整的英文单词组合命名变量和函数,以便面试官一眼能读懂代码的意图。

    3-3代码的完整性

    面试官会关注思考的是否周全:是否完成了基本功能,输入边界值是否得到正确的输出,对不合规范的输入是否做了合理的错误处理

    3-3-1从3方面确保代码的完整性

    功能测试、边界测试、负面测试(错误的例子)

    3-3-3种错误的处理方式

    第一种:函数用返回值告知调用者是否出错。比如很多Windows的API就是这个类型(返回值0表示成果),不直观
    第二种:当发生错误时设置一个全局变量,此时我们可以在返回值中传递计算结果了。这种方法比第一种方法更加方便(直观)。缺点是调用者很容易忘记检查全局变量,因此在调用出错的时候忘记做响应的错误处理,从而留下安全隐患。
    第三种:抛出异常,C#有,C没有。优点:可以为不同类型的错误定义不同类型的异常,逻辑清晰;缺点:当抛出异常时,程序的执行会打乱正常顺序,对程序的性能有很大影响。

    面试的时候采用哪种错误处理方式要看面试官的要求

    面试题11 数值的整数次方 Leetcode50 myPow实现乘方函数

    要求实现数的乘方
    面试小提示!非常重要!
    由于计算机表示小数(包括float型和double型)都有误差,我们不能直接用等号(==)判断两个数是否相等,如果两个小数的差的绝对值很小,比如小于0.0000001,就可以认为它们相等
    Leetcode50:http://blog.csdn.net/u011462357/article/details/79339875
    POW2

    面试题17 打印从1到最大的 n位数(还没写)

    面试题18-1 删除链表的节点 Leetcode237 Delete Node in a Linked List

    书中的C++解法涉及到一个问题,为什么要在删除一个节点后还要把该节点赋为NULL。个人认为这是一种鲁棒性的体现,参见:https://www.2cto.com/kf/201510/447386.html
    重点:delete是释放指针指向的内存,而并不是指针本身所占有的内存。
    Leetcode 237. Delete Node in a Linked List(和书上的例题很像,但没给头节点,也确定不是尾节点)
    Write a function to delete a node (except the tail) in a singly linked list, given only access to that node.
    Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function.

    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution(object):
        def deleteNode(self, node):
            """
            :type node: ListNode
            :rtype: void Do not return anything, modify node in-place instead.
            """
            node.val = node.next.val
            node.next = node.next.next

    时间复杂度:O(1)
    思路重点:

  • 当我们想删除一个节点时,并不一定要删除该节点本身。可以先把下一个节点的内容复制出来覆盖被删除的节点的内容,然后把下一个节点删除。
  • 因为不用知道要删除的节点的前一个节点,所以不用遍历链表获得要删除节点的前一个节点(此思路时间复杂度O(n))。
  • 注意:上述代码不完美,因为它基于假设:要删除的节点的确在链表中,我们需要O(n)的时间才能判断链表中是否包含某一节点。受到O(1)时间的限制,我们不得不把确保节点在链表中的责任推给了函数的调用者。面试时可以和面试官讨论这个假设,面试官会觉得我们考虑问题非常全面。(这段是书中说的)

    面试题18-2 删除链表中重复的节点

    面试题19 正则表达式匹配

    面试题20 表示数值的字符串

    面试题21 调整数组顺序使奇数位于偶数前面

    3-4代码的鲁棒性

    面试题22 链表中倒数第k个节点

    面试题23 链表中环的入口节点

    面试题24 反转链表(Leetcode206 Reverse Linked List)

    详解参见我的链表专题:
    http://blog.csdn.net/u011462357/article/details/79379267

    面试题25 合并两个排序的链表(Leetcode21. MergeTwoSortedLists)

    详解参见我的链表专题:
    http://blog.csdn.net/u011462357/article/details/79379267

    面试题26 树的子结构(Leetcode572.Subtree of Another Tree)

    详解参见我的树专题:http://blog.csdn.net/u011462357/article/details/79389115

    3-5本章小结

    欢迎使用Markdown编辑器写博客

    本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦:

    • Markdown和扩展Markdown简洁的语法
    • 代码块高亮
    • 图片链接和图片上传
    • LaTex数学公式
    • UML序列图和流程图
    • 离线写博客
    • 导入导出Markdown文件
    • 丰富的快捷键

    快捷键

    • 加粗 Ctrl + B
    • 斜体 Ctrl + I
    • 引用 Ctrl + Q
    • 插入链接 Ctrl + L
    • 插入代码 Ctrl + K
    • 插入图片 Ctrl + G
    • 提升标题 Ctrl + H
    • 有序列表 Ctrl + O
    • 无序列表 Ctrl + U
    • 横线 Ctrl + R
    • 撤销 Ctrl + Z
    • 重做 Ctrl + Y

    Markdown及扩展

    Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成格式丰富的HTML页面。 —— [ 维基百科 ]

    使用简单的符号标识不同的标题,将某些文字标记为粗体或者斜体,创建一个链接等,详细语法参考帮助?。

    本编辑器支持 Markdown Extra ,  扩展了很多好用的功能。具体请参考Github.

    表格

    Markdown Extra 表格语法:

    项目 价格
    Computer $1600
    Phone $12
    Pipe $1

    可以使用冒号来定义对齐方式:

    项目 价格 数量
    Computer 1600 元 5
    Phone 12 元 12
    Pipe 1 元 234

    定义列表

    剑指OFFER目录及对应LEETCODE习题
    第一章 面试常识
    第二章 面试需要的基础知识
    2.3数据结构
    2.3.1数组 http://mp.blog.csdn.net/postedit/79278482(同剑指面试题3)
    2.3.2字符串 http://mp.blog.csdn.net/postedit/78593652(类似剑指面试题4 替换空格)
    2.3.3链表(面试题5 从头到尾打印链表)
    2.3.4树 (面试题6 重建二叉树)
    2.3.5栈和队列(面试题7 用两个栈实现一个队列)
    2.4算法和数据操作
    排序和查找是面试中的重点,应随时,完整地能写出 二分查找,归并排序,快速排序的代码
    栈比循环形式简单,但效率不如循环高
    要能比较冒泡排序,快速排序,归并排序的优劣,空间复杂度,平均时间复杂度和最差时间复杂度
    2.4.1查找和排序
    查找不外乎顺序查找,二分查找,哈希表查找和二叉排序树查找
    第三章 su
    定义 C

    定义 D

    定义D内容

    代码块

    代码块语法遵循标准markdown代码,例如:

    @requires_authorization
    def somefunc(param1='', param2=0):
        '''A docstring'''
        if param1 > param2: # interesting
            print 'Greater'
        return (param2 - param1 + 1) or None
    class SomeClass:
        pass
    >>> message = '''interpreter
    ... prompt'''

    脚注

    生成一个脚注1.

    目录

    [TOC]来生成目录:

    数学公式

    使用MathJax渲染LaTex 数学公式,详见math.stackexchange.com.

    • 行内公式,数学公式为: Γ ( n ) = ( n 1 ) ! n N
    • 块级公式:

    x = b ± b 2 4 a c 2 a

    更多LaTex语法请参考 这儿.

    UML 图:

    可以渲染序列图:

    Created with Raphaël 2.1.2 张三 张三 李四 李四 嘿,小四儿, 写博客了没? 李四愣了一下,说: 忙得吐血,哪有时间写。

    或者流程图:

    Created with Raphaël 2.1.2 开始 我的操作 确认? 结束 yes no
    • 关于 序列图 语法,参考 这儿,
    • 关于 流程图 语法,参考 这儿.

    离线写博客

    即使用户在没有网络的情况下,也可以通过本编辑器离线写博客(直接在曾经使用过的浏览器中输入write.blog.csdn.net/mdeditor即可。Markdown编辑器使用浏览器离线存储将内容保存在本地。

    用户写博客的过程中,内容实时保存在浏览器缓存中,在用户关闭浏览器或者其它异常情况下,内容不会丢失。用户再次打开浏览器时,会显示上次用户正在编辑的没有发表的内容。

    博客发表后,本地缓存将被删除。 

    用户可以选择 把正在写的博客保存到服务器草稿箱,即使换浏览器或者清除缓存,内容也不会丢失。

    注意:虽然浏览器存储大部分时候都比较可靠,但为了您的数据安全,在联网后,请务必及时发表或者保存到服务器草稿箱

    浏览器兼容

    1. 目前,本编辑器对Chrome浏览器支持最为完整。建议大家使用较新版本的Chrome。
    2. IE9以下不支持
    3. IE9,10,11存在以下问题
      1. 不支持离线功能
      2. IE9不支持文件导入导出
      3. IE10不支持拖拽文件导入


    1. 这里是 脚注内容.

    猜你喜欢

    转载自blog.csdn.net/u011462357/article/details/79281109