Python笔记题编程题答案

时间:2022-07-23
本文章向大家介绍Python笔记题编程题答案,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

有什么问题或资源分享欢迎大家后台留言或添加微信

最近刚到一个新公司上班,比较忙,不能每天分享文章,希望大家见谅。我会尽最大努力找时间进行分享。

今天分享下笔试题编程题目答案。程序题答案大家可以自己去运行试试看,如果有不明白的可以后台留言或加小编微信。

1、实现二分查找

__author__ = 'demon'

"""
    二分查找
    针对已经有序的数据可以采用二分查找
    一定要注意 有序 这个前提
"""
def binary_search(alist, item):
    """二分查找,递归"""
    n = len(alist)
    if n > 0:
        mid = n//2
        if alist[mid] == item:
            return True
        elif item < alist[mid]:
            return binary_search(alist[:mid], item)
        else:
            return binary_search(alist[mid+1:], item)
    return False

def binary_search_2(alist, item):
    """二分查找, 非递归"""
    n = len(alist)
    first = 0
    last = n-1
    while first <= last:
        mid = (first + last)//2
        if alist[mid] == item:
            return True
        elif item < alist[mid]:
            last = mid - 1
        else:
            first = mid + 1
    return False


if __name__ == "__main__":
    li = [17, 20, 26, 31, 44, 54, 55, 77, 93]
    print(binary_search(li, 55))
    print(binary_search(li, 100))
    print(binary_search_2(li, 55))
    print(binary_search_2(li, 100))

2、实现简单的二叉树,并实现层次遍历与深度遍历

"""
    注意四点:
    1. 首先要定义数据结构,即定义结点类与二叉树类
    2. 层次遍历就是广度遍历
    3. 深度遍历分为三种:先序、中序和后序。其中先、中、后分别表示根结点查询的顺序。
       即先序:根左右。中序:左根右。后序:左右根。
    4. 深度遍历的重要思想就是递归。但也可以不用递归实现,感兴趣的读者可以自己尝试实现
"""
# 定义结点
class Node(object):
    """结点类"""

    def __init__(self, elem=-1, lchild=None, rchild=None):
        self.elem = elem  # 元素值
        self.lchild = lchild  # 左孩子
        self.rchild = rchild  # 右孩子


class Tree(object):
    """二叉树类"""

    def __init__(self, root=None):
        self.root = root

    def add(self, elem):
        """为树添加结点"""

        # 1. 创建结点
        node = Node(elem)

        # 2. 如果当前树是一个空树,直接将当前结点赋值为根结点
        if self.root is None:
            self.root = node
            return

        # 3. 如果当前不是一个空树,则查找该结点应该插入的位置
        queue = []
        queue.append(self.root)

        while queue:
            cur_node = queue.pop(0)

            if cur_node.lchild is None:
                cur_node.lchild = node
                return

            if cur_node.rchild is None:
                cur_node.rchild = node
                return

            queue.append(cur_node.lchild)
            queue.append(cur_node.rchild)

    def breadth_travel(self):
        """广度优先(层次遍历)"""

        # 1. 如果当前是空树,直接返回
        if self.root is None:
            return

        # 2. 如果不是空树,则层次遍历,将每次遍历的层次结点放入队列中
        queue = [self.root]
        while queue:
            cur_node = queue.pop(0)
            print(cur_node.elem, end=" ")

            if cur_node.lchild is not None:
                queue.append(cur_node.lchild)

            if cur_node.rchild is not None:
                queue.append(cur_node.rchild)

    def preorder(self, node):
        """先序遍历"""
        if node is None:
            return
        print(node.elem, end=" ")
        self.preorder(node.lchild)
        self.preorder(node.rchild)

    def inorder(self, node):
        """中序遍历"""
        if node is None:
            return
        self.inorder(node.lchild)
        print(node.elem, end=" ")
        self.inorder(node.rchild)

    def postorder(self, node):
        """后序遍历"""
        if node is None:
            return
        self.postorder(node.lchild)
        self.postorder(node.rchild)
        print(node.elem, end=" ")


if __name__ == '__main__':
    tree = Tree()
    tree.add(1)
    tree.add(2)
    tree.add(3)
    tree.add(4)
    tree.add(5)
    tree.add(6)
    tree.add(7)
    tree.breadth_travel()

3、实现字典的 key 取交集

# 主要利用 set 取交集的方式
# 要知道字典的 key 是重复的,它就是一个 set
k1 = {"1": 1, "2": 2}
k2 = {"2": 2}
print(k1.keys() & k2.keys())

# 当然也可以用列表推导来实现,但我觉得这个主要考查的是上面的那种实现方式
inter = [x for x in k1 if  x in k2]

4、实现一个 LRU ,使得查询、删除与添加的时间复杂度为O(logn)

"""
    这个题在 leetcode 上有出现过,而且 leetcode 上要求的时间复杂度是 O(1)
    面试时只要讲思路,没说要具体实现,所以这里也只提供思路
    1. 使用的数据结构是 循环链表  +  字典的结构,这里的字典等价于 JAVA 中的 HashMap
    2. 选择链表的原因在于插入和删除速度都是O(1)
    3. 链表的缺点在于查找慢,是O(n),所以用一个字典来存储链表中的结点,key为结点的值
    4. 当我们要查找时,先通过字典来拿到结点。因为是循环链表,所以可以很快知道前驱和后继,从而可以进行插入和删除操作。这样查找的效率也变成了O(1)
    5. 第四点也就是为什么要使用循环链表的原因
"""

5、嵌套列表的扩展,如[1, 2, [3, [4, [5, 6]]]] 输出为 [1, 2, 3, 4, 5,6]

# 第一种实现方式
# 递归实现压平嵌套列表
def flatten(l):
    res = []
    for x in l:
        if not isinstance(x, list):
            res.append(x)
        else:
            res.extend(flatten(x))
    return res


l = [1, 2, [3, 4], [5, [6, 7, [8, 9]]]]
print(flatten(l))
l = ['a', 'b', ['b', 'c'], ['d', ['e', ['f', ['e']]]]]
print(flatten(l))

# 在网上看到有用一句话实现上面递归的
flat=lambda L: sum(map(flat,L),[]) if isinstance(L,list) else [L]

对于最后一题,如果大家有更好的实现,欢迎分享。我会选出我认为最好的答案送小红包一个~~

如果大家有什么面试笔试经验,欢迎分享~~

愿关注我们的人都能找到

属于自己的皮球