笔记

知识补充

浅拷贝与深拷贝:

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
三、赋值和浅拷贝的区别
当我们把一个对象赋值给一个新的变量时,赋的其实是该对象的在栈中的地址,而不是堆中的数据。也就是两个对象指向的是同一个存储空间,无论哪个对象发生改变,其实都是改变的存储空间的内容,因此,两个对象是联动的。
浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。即默认拷贝构造函数只是对对象进行浅拷贝复制(逐个成员依次拷贝),即只复制对象空间而不复制资源。
图片说明
浅拷贝不管数据多复杂,只会拷贝一层。
https://www.cnblogs.com/blaomao/p/7239203.html

python中调用的类函数类成员记得加上self.
此外,类函数必须有一个成员变量self(静态函数出外)

补码:正数的补码与原码相同。负数的补码等于其原码的符号位不变,数值部分的各位取反,然后整个数加1。
反码:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外

python中首先明确一点就是二进制没有位数的概念,所以也就无法获得负数真实表示方法

n = -3
n = n & 0xffffffff #n=4294967293
bin(n)#查看二进制形式:'0b11111111111111111111111111111101'

获得的最终结果python会认为是一个正数(因为没有位数的概念,所以首位的1并不代表符号位),那么获得

0b11111111111111111111111111111101

只是形式上和-3的补码相同。
python中,对于负数,无论是右移操作,还是n&(n-1)操作,都会陷入死循环。
所以利用上述这个小技巧,将负数的影响用于0xffffffff相与变为python认为的正数(与机器中的补码相同)。
链接:https://www.nowcoder.com/questionTerminal/8ee967e43c2c4ec193b040ea7fbb10b8?answerType=1&f=discussion
来源:牛客网

如何将整数转化成二进制

  • 采用 python 自带了方法 bin 函数,比如 bin(12345) 回返回字符串 '0b11000000111001', 这个时候在把0b去掉即可:

    bin(12345).replace('0b','')
    '11000000111001'

  • 也可以采用字符串的 format 方法来获取二进制:

    "{0:b}".format(12345)
    '11000000111001'

元组

tup1=(1)
tup2=(1,)
print(tup1, tup2)
>>>
1 (1,)

显然,定义元组时,如果单元素不加逗号会造成系统认为括号为运算符,所以tup1为int而不是tuple

函数补充

string 中的count函数可以返回特定字符串在string中出现的次数
关键在于矩阵是有序的,在python中tuple就是二维的,可以通过下表访问,并len(array)长度便是行
math.pow(x,y) x^y
math.floor 下舍整数
math.ceil 上舍整数

enumerate():

该函数在字面上是枚举、列举的意思,用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中,可同时得到数据对象的值及对应的索引值。如对于下面的例子:
图片说明
图片说明

collections中deque的使用:

from collections import deque
双端队列。可两侧访问:
deque1.maxlen 最大长度 如果制定了,那么添加元素时,如果超过你maxlen,旧元素会被删除。
deque1.append() deque1.appendleft()一个默认右侧一个左侧添加元素
deque1.extend() deque1.extendleft()添加列表
deque1.pop() deque.popleft() 出队列
count() clear() remove() insert(index,x) reverse()翻转
copy浅拷贝

list.reverse 列表翻转。
s.join(ite) 添加字符串
s[::-1]可以实现字符串的逆向输出

如何保留两位小数:

math : round(x[,n]):x为数字,n为保留小数点后的位数,但是如果3.5那么输出的结果为3.5而不是3.50
那么如何让其输出3.50呢?
这样可以:
'%.2f'%x

name属性

一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用name属性来使该程序块仅在该模块自身运行时执行。

#!/usr/bin/python3
# Filename: using_name.py

if __name__ == '__main__':
   print('程序自身在运行')
else:
   print('我来自另一模块')
$ python using_name.py
程序自身在运行

$ python
>>> import using_name
我来自另一模块
>>>

python 栈

listNode的实操,list的逆序输出的3方法

list1=[1,2,34,5]
list1[::-1]                #切片
list(list1.reverse())    #list自带的reverse,直接逆向输出
list(reversed(list))    #利用reversed,但需要列表化

list的压栈出栈用法

append、pop均默认最后一个元素
一般讲list当做C++中的栈,append,pop可以当做进栈出栈

二叉树

二叉树-前中后序

https://www.cnblogs.com/bigsai/p/11393609.html

重建二叉树:

中心遍历法:

class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
    # write code here
        if len(pre) == 0:
            return None
        if len(pre) == 1:
            return TreeNode(pre[0])
        root = TreeNode(pre[0])
        tinL = tin[:tin.index(pre[0])]
        tinR = tin[tin.index(pre[0]) + 1:]
        root.left = self.reConstructBinaryTree(pre[1:len(tinL)+1], tinL)
        root.right = self.reConstructBinaryTree(pre[len(tinL)+1:], tinR)
        return root

二分查找:

有序
https://xxoo521.com/2019-12-24-xuan-zhuan-shu-zu/
注意:python中逻辑运算符为and not or而不是!|&。同时,注意math的floor,ceil返回的为浮点数。

斐波那契数列

循环 or 递归(会超时)
注意:青蛙跳台阶的变种
变态跳台阶:
链接:https://www.nowcoder.com/questionTerminal/22243d016f6b47f2a6928b4313c85387?answerType=1&f=discussion
来源:牛客
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

分析
设nn 级台阶有f(n)f(n) 种跳法,根据最后一次跳台阶的数目可以分解为最后一次一级,则前面需要跳n-1n−1 级,有f(n-1)f(n−1) 种跳法;最后一次跳两级,则前面需要跳n- 2n−2 级,有f(n-2)f(n−2) 种跳法。以此类推 易知,
f(n)=f(n-1)+f(n-2)+……f(0)
f(n-1)=f(n-2)+…f(0)
两式相减得,
f(n)=2f(n-1)f(n)=2f(n−1)

栈的利用

输入一个链表,反转链表后,输出新链表的表头

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        # write code here
        if not pHead:
            return None
        list0=[]
        Node0=pHead
        while Node0:
            list0.append(Node0)
            Node0=Node0.next
        head=list0.pop()
        Node1=head
        while list0:
            Node1.next=list0.pop()
            Node1=Node1.next
        Node1.next=None                #很关键。最后出栈的是pHead,但是你原来的pHead是指向之前的第二个,也就是现在列表的倒数第二个。致使死循环
        return head

注意:链表一定要写如果链表空的返回值

搜索树,子树☆☆

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

class Solution:
    def IsameTree(self,root1,root2):
        if not root2:
            return True
        if not root1 and root2:
            return False
        if root1.val==root2.val:
            return self.IsameTree(root1.left,root2.left) and self.IsameTree(root1.right,root2.right)
        else:
            return False

    def HasSubtree(self, pRoot1, pRoot2):
        # write code here
        if not pRoot2:
            return False
        if not pRoot1 and pRoot2:
            return False
        flag=False
        if pRoot1.val==pRoot2.val:
            flag=self.IsameTree(pRoot1,pRoot2)
        if not flag:
            flag=self.HasSubtree(pRoot1.left,pRoot2)
            if not flag:
                flag=self.HasSubtree(pRoot1.right,pRoot2)
        return flag

算法

深度优先-广度优先-区别:

https://blog.csdn.net/yishuige/article/details/51769997
https://blog.csdn.net/yimixgg/article/details/90023121
https://blog.csdn.net/github_38818603/article/details/81288659
二叉树DFS,BFS:
https://blog.csdn.net/mingwanganyu/article/details/72033122?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
昨晚一直在想深度优先广度优先的区别,都是一样的程序,只有栈和队列不同而已,就造成了深度和广度的区别,那么是为什么呢?
今早上灵机一闪,问题就出在栈和队列,这两者的存储机制不同的。
深度优先:
栈先进后出,假设二叉树前序遍历[w,q,,r,t,e,y,u]
w进栈,q进栈,然后是q的子树r,t。而不是w的右子树e。然后出栈便是trq。然后eyu进栈,uyew出栈。这同时使用了回溯。
广度优先:
队列先进先出,,同样的二叉树。
w进,qe进

排序方法

快排:

时间复杂度O(nlog(n))-O(n^2)

堆排

时间复杂度O(nlog(n))

归并排序

时间复杂度O(log(n))

查找

二分查找

时间复杂度O(logn)

BFPRT(线性查找算法)

深度优先、广度优先

关于python的输入输出

这个主要针对第一次笔试出现的问题,不晓得python如何循环输入输出。
首先了解python的sys模块:
stdin标准输入:
sys.stdin.readline(): return字符串,如果需要int,float类型,则需要进行强制类型转化
使用map函数进行转化。

import sys
while True:
    line=sys.stdin.readline()
    if line == '\n':
        break
    line=line.split(' ')
    print(line)

readlines

与readline对应,其读取多行,以Ctrl+D结束,返回的为列表注意列表中的每一项含有'\n'

map函数的使用:

map(func,iter)
第一个参数func以参数序列中的每一个元素调用func函数,返回包含每次func函数返回的新列表

那么:

map(int,line.split())

即可将所有转化为int

split的使用:

s.split() 如果无参数默认空格,将s分割返回一个列表
split可以有参数,s.split('\n')则是将字符串s转化为以'\n'分割而成的字符串列表
sprip()只能删除开头和结尾的特定字符,默认为空格,不能操作中间的字符

全部评论

相关推荐

如题
投递阿里巴巴集团等公司10个岗位 >
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务