Python面试题122-137算法和数据结构

这篇博客汇总了Python面试中关于算法和数据结构的常见题目,包括二分查找、单例模式实现、斐波那契数列、冒泡排序、快速排序、拓扑排序等,并提供了详细解析和实现方法。同时,还涵盖了链表反转、数据流中位数、二叉搜索树等问题,是Python面试准备的宝贵资料。
摘要由CSDN通过智能技术生成

参考自:https://cloud.tencent.com/developer/article/1490616(题目来源)

所有题目

算法和数据结构

122.已知:

AList = [1,2,3]
BSet = {
   1,2,3}
(1) 从 AList 和 BSet 中 查找 4,最坏时间复杂度哪个大?

对于查找,列表和集合的最坏时间复杂度都是O(n),所以一样的。

(2) 从 AList 和 BSet 中 插入 4,最坏时间复杂度哪个大?

列表操作插入的最坏时间复杂度为o(n), 集合为o(1),所以Alist大。set是哈希表所以操作的复杂度基本上都是o(1)

123.用 Python 实现一个二分查找的函数
二分搜索是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

#法1
def binary_search(arr, target):
    n = len(arr)
    left = 0
    right = n - 1
    while left <= right :
        mid = (left + right) // 2
        if arr[mid] < target:
            left = mid + 1
        elif arr[mid] > target:
            right = mid - 1
        else :
            print(f"index:{
     mid},value:{
     arr[mid]}")
            return True
    return False

if __name__ == '__main__':
    l = [1, 3, 4, 5, 6, 7, 8]
    binary_search(l, 8)
#输出
index:6,value:8

#法2 使用到了递归调用
# 返回 x 在 arr 中的索引,如果不存在返回 -1
def binarySearch (arr, l, r, x): 
    # 基本判断
    if r >= l: 
        mid = int(l + (r - l)/2) 
        # 元素整好的中间位置
        if arr[mid] == x:
            print('刚好在中间')
            return mid         
        # 元素小于中间位置的元素,只需要再比较左边的元素
        elif arr[mid] > x:
            print('在左边')
            return binarySearch(arr, l, mid-1, x) 
        # 元素大于中间位置的元素,只需要再比较右边的元素
        else:
            print('在右边')
            return binarySearch(arr, mid+1, r, x) 
    else: 
        # 不存在
        return -1
# 测试数组
arr = [ 2, 3, 4, 10, 40 ] 
x = 10
# 函数调用
result = binarySearch(arr, 0, len(arr)-1, x) 

if result != -1: 
    print ("元素在数组中的索引为 %d" % result )
else: 
    print ("元素不在数组中")
#输出
在右边
刚好在中间
元素在数组中的索引为 3

124.python 单例模式的实现方法
单例(Singleton)

单例是一种设计模式,应用该模式的类只会生成一个实例。

单例模式保证了在程序的不同位置都可以且仅可以取到同一个对象实例:如果实例不存在,会创建一个实例;如果已存在就会返回这个实例。因为单例是一个类,所以你也可以为其提供相应的操作方法,以便于对这个实例进行管理。

4种方法实现单例模式:

  1. 使用函数装饰器实现单例
  2. 使用类装饰器实现单例
  3. 使用 new 关键字实现单例
  4. 使用 metaclass 实现单例
    预备知识:装饰器
#1. 使用函数装饰器实现单例
def singleton(cls):
    _instance = {
   }

    def inner():
        if cls not in _instance:
            _instance[cls] = cls()
        return _instance[cls]
    return inner
    
@singleton
class Cls(object):
    def __init__(self):
        pass

cls1 = Cls()
cls2 = Cls()
print(id(cls1) == id(cls2))
#输出
True

更多单例模式参考:
https://zhuanlan.zhihu.com/p/37534850

另外实现单例的方法:使用模块
其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:
mysingleton.py

class Singleton(object):
    def foo(self):
        pass
singleton = Singleton()

将上面的代码保存在文件 mysingleton.py 中,要使用时,直接在其他文件中导入此文件中的对象,这个对象即是单例模式的对象

from mysingleton import singleton as s
s1=s
s2=s
print(id(s1)==id(s2))
#输出
True

125.使用 Python 实现一个斐波那契数列

斐波那契数列:数列从第 3 项开始,每一项都等于前两项之和。

#1.递归法,写法最简洁,但是效率最低,会出现大量的重复计算,时间复杂度O(1.618^n),而且最大深度为1000
def fib_recur(n):
    if n <= 1:
        return n
    return fib_recur(n-1) + fib_recur(n-2)

for i in range(1, 20):
    print(fib_recur(i), end=' ')
    
#2.类似递归法,使用for循环实现
fibs = [0,1]
for i in range(8):
    fibs.append(fibs[-2] + fibs[-1])
print(fibs)

#3.递增法,时间复杂度是 O(n),呈线性增长,如果数据量巨大,速度会越拖越慢
def fibonacci(num):
    a, b = 0, 1
    l = [a, b]
    for i in range(num):
        a, b = b, a + b
        l.append(b)
    return l

if __name__ == '__main__':
    print(fibonacci(10))
    
#4. yield关键字
def fun(n):
    a, b = 0, 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值