算法题

本文探讨了Python编程中的算法应用,包括手写归并排序算法及其复杂度分析,组合数学问题(组成无重复数字的三位数),单链表反转,寻找二维坐标内的最大面积容器,寻找数组中最大的10个数,两数之和问题,有序列表合并,数组元素乘积计算,柱状图中雨水的体积,以及递归遍历文件夹获取所有文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用Python实现效果

请手写归并排序算法,并且用注释写出思路,并且指出时间复杂度

def mergesort(a,b):
    c = []
    len1 = len(a)
    len2 = len(b)
    j,i = 0, 0
    while i < len1 and j < len2:
        if a[i] > b[j]:
            c.append(b[j])
            j += 1
        else:
            c.append(a[i])
            i += 1
    while i < len1:
        c.append(a[i])
        i += 1
    while j < len2:
        c.append(b[j])
        j += 1
    return c


def separateList(q, first, last):
    if first < last:
        mid = int((first + last)/2)
        separateList(q, first, mid)
        separateList(q, mid+1, last)
        a = q[first:mid+1]
        b = q[mid+1:last+1]
        c = mergesort(a, b)
        start = first
        for i in c:
            q[start] = i
            start += 1
        return q

有四个数字:1、2、3、4,能组成多少个互不相同且无重复数字的三位数?

def random_number(number):
    w = 0
    for i in range(1, number):
        for n in range(1, number):
            for m in range(1, number):
                if i != n and n != m and i != m:
                    print("{}{}{}".format(i, n, m))
                    w += 1
    print("total:{}".format(w))

单链表反转

def reverse_list(list_input):
    relist=[]
    for i in range (len(list_input)):
        relist.append(list_input.pop())
    return relist

给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。

在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

def func(arr):
    left = 0
    right = len(arr) - 1
    mianji = 0
    while left < right:
        mianji = max(mianji, (right - left) * min(arr[left], arr[right]))
        if arr[left] < arr[right]:
            # 左边小 移动左边  反之 移动右边
            left += 1
        else:
            right -= 1
        print(mianji)
    return mianji

现在有n个数(n>10000),设计算法,按大小顺序得到前10大的数

def front10(nums):
    for x in range(10):
        print("====={}====".format(x))
        for i in range(len(nums) - 1):
            if nums[i] > nums[i + 1]:
                nums[i], nums[i + 1] = nums[i + 1], nums[i]
                print(nums)
front10([3, 1, 5, 2, 9, 8, 7, 31, 12, 24, 16, 11, 19, 22, 50, 39, 29, 13])

在列表中找到两个数的和等于给出的数(返回找到的下标)


def equalSum(list, target):
    for i, item1 in enumerate(list):
        for j, item2 in enumerate(list[i + 1:]):
            if item1 + item2 == target:
                print(item1, "+", item2, "=", target)
                print("下标1:", i, " 下标2:", j)


equalSum([1, 2, 3, 4, 5, 6, 7, 8, 9], 12)

8、l1 = [1,4,5] l2 = [2,3,6] 合并有序列表l1和l2,要求时间复杂度为O(n)

def hebing(list1, list2):
    result = []
    while list1 and list2:
        if list1[0] < list2[0]:
            result.append(list1[0])
            del list1[0]
        else:
            result.append(list2[0])
            del list2[0]
    if list1:
        result.extend(list1)
    if list2:
        result.extend(list2)
    print(result)
    return result

给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i]

等于 nums 中除 nums[i] 之外其余各元素的乘积。也就是说,新的结果列表中,每个位置上的数据,

来自于除原始列表相同位置上的其他位置的乘积


def productExceptSelf(nums):
    """
    :type nums: List[int]
    :rtype: List[int]
    """
    n = len(nums)
    res = [1] * n

    for i in range(n - 1):
        res[i + 1] = res[i] * nums[i]
    right = 1
    for i in range(n - 1, -1, -1):
        res[i] *= right
        right *= nums[i]

    return res


if __name__ == "__main__":
    q = [2, 3, 1, 7, 5, 9, 10, 4, 6, 8]  # 请手写归并排序算法,并且用注释写出思路,并且指出时间复杂度
    first = 0
    last = len(q) - 1
    print(separateList(q, first, last))

    random_number(5)  # 有四个数字:1、2、3、4,能组成多少个互不相同且无重复数字的三位数?

    print(reverse_list([1, 5, 8, 6]))  # 单链表反转
        
    
    print("最终结果:", func([1, 2, 3, 4, 5, 6, 7]))  # 容器可以容纳最多的水

    print(hebing([3, 4, 7, 9, 11], [1, 2, 5, 8, 13, 20]))  # 合并两个列表

    print(productExceptSelf([1, 2, 5, 8, 13, 20]))

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水

class Solution():
    def trap(self, height):
        n = len(height)
        if n <= 2: return 0
        left = [-1] * n
        right = [-1] * n

        max_idx = 0
        max_height = height[0]
        left[0] = 0
        for i in range(1, n):
            if height[i] >= max_height:
                max_idx = i
                max_height = height[i]
            left[i] = max_idx

        right[n-1] = n - 1
        max_idx = n - 1
        max_height = height[n-1]
        for i in range(n-2, -1, -1):
            if height[i] >= max_height:
                max_idx = i
                max_height = height[i]
            right[i] = max_idx

        tot = 0
        for i in range(0, n):
            tot += min(height[left[i]], height[right[i]]) - height[i]

        return tot

s = Solution()
print(s.trap([0,1,0,2,1,0,1,3,2,1,2,1]))

现在有n个数(n>10000),设计算法,按大小顺序得到前10大的数

# 将一个数组按照左大右小顺序排好
def inser_sort(list):
    for i in range(1, len(list)):
        tem = list[i]
        j = i - 1
        while j >= 0 and list[j] < tem:
            list[j + 1] = list[j]
            j = j - 1
        list[j + 1] = tem


def topk(li, k):
    list = li[0:k]  # 创建一个长度为k的数组来储存最大的k个数
    inser_sort(list)  # 将这个K数组先按照大小顺序用插入偶排序排好
    # print(list)
    # print(list[-1])

    for i in range(k, len(li)):  # 将剩下的数字依次拿到
        # 将拿到的数字和数组中最小的数字做对比
        if li[i] > list[-1]:  # 如果比最小的数字大,就做交换,把最小的数字换成取到的数
            list[-1] = li[i]
            # 交换之后进行排序
            inser_sort(list)
    print(list)

topk([30000,20000,50000,40000],30000)

遍历目录下所有文件(包括子文件夹中所有文件)(递归10分)

import os
def getAllFiles(path):
    for file in os.listdir(path):  # 遍历当前目录下所有文件
        filePath = os.path.join(path, file)  # 生成当前目录下文件的绝对路径
        if os.path.isfile(filePath):  # 如果这个路径是文件而不是文件夹则找到一个文件
            print("get file: ", filePath)
        else:   # 如果这个路径是文件夹,则递归调用此函数
            getAllFiles(filePath)

getAllFiles('./day5')

# 在这里的路径写入的是  当前项目的任意位置下的目录,然后遍历出来的是该目录下的所有文件

在列表中找到两个数的和等于给出的数(返回找到的下标)

如:li = [1,2,4,3,5,]
target = 5
返回0,2
(10分)

def twosum(alist, targetnum):
    for i, j in enumerate(alist):
        k = i + 1
        if alist[k:].count(targetnum - j) > 0:
            for n in range(alist[k:].count(targetnum - j)):
                b = alist.index(targetnum - j, k)
                print(i, b)
                k = b + 1

li = [1,2,4,3,5,]
twosum(li, 6)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值