python常见算法题

算法效率分析分为两种:第一种是时间效率,第二种是空间效率。时间效率被称为时间复杂度,而空间效率被称作空间复杂度。 时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间。

  • 例如函数执行的基本操作次数:F(N) = 2N2+2N+10,则对应的时间复杂度是:O(N2),N的2次方

1、数组中元素差值比较

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一次计算,设计一个算法来计算你所能获取的最大值。
示例 1:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(价格 = 1)的时候买入,在第 5 天(价格 = 6)的时候抛出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
示例 2:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
请给出时间复杂度O(n)方案,并给出测试用例设计。

def maxMoney(args):
    max_money = 0
    if not isinstance(args, list):
        print("必须传递数组类型")
        return max_money

    if len(args) <= 1:
        return max_money

    for i in range(len(args)-1):
        # 数组截取,从剩余的数组中,选取最大值,然后与起始值做减法
        max_element = max(args[i+1:len(args)])
        if max_element > args[i]:
            max_money_temp = max_element - args[i]
            # max_money与每次循环时计算的最大值作比较,取最大值
            max_money = max(max_money, max_money_temp)
    return max_money


print(maxMoney("aa"))   # 必须传递数组类型 0
print(maxMoney([]))  # 0
print(maxMoney([7]))  # 0
print(maxMoney([0]))   # 0
print(maxMoney([-1]))    # 0
print(maxMoney([-1, 0]))  # 股票价格不能包含负数   0
print(maxMoney([7, 8]))    # 1
print(maxMoney([7, 7]))   # 0
print(maxMoney([7, 6]))    # 0
print(maxMoney([7, 1, 5, 3, 6, 4]))    # 5

2. 数组中的两个元素匹配

设计一个算法,找出数组中两数之和为指定值的所有整数对。一个数只能属于一个数对。
示例 1:
输入: nums = [5,6,5], target = 11,输出: [[5,6]]

示例 2:
输入: nums = [5,6,5,6], target = 11,输出: [[5,6],[5,6]]

# 方法1:排序后双向指针循环,将target与最左边最小值和最右边最大值之和做比较。排序后时间复杂度为O(NlogN)
def matchTarget(args, target):
    matches = []
    if not isinstance(args, list):
        print("必须传递数组类型")
        return matches

    if len(args) < 2:
        return matches

    args.sort()    # 会改变原数组值
    i = 0
    j = len(args)-1
    while i < j:
        if args[i] + args[j] < target:
            i += 1
        elif args[i] + args[j] > target:
            j -= 1
        else:
            matches.append([args[i], args[j]])
            i += 1
            j -= 1
    return matches

# 方法二:
# hash做存储target-args[i]的值
# 如果tmp中不存在对应target-args[i]的值,则说明当前元素和之前的都不匹配。然后需要将当前元素添加到tmp中。
# 如果tmp中存在对应target-args[i]的值,则说明当前元素和之前的某个元素匹配了。然后tmp中移除匹配的元素(这样就是用tmp达到了一个不重复使用之前的),并且将匹配数数据添加到matches中
# 时间复杂度:O(N)
def matchTarget2(args, target):
    matches = []
    matches2 = {}
    if not isinstance(args, list):
        print("必须传递数组类型")
        return matches

    if len(args) < 2:
        return matches

    tmp = {}
    for i in range(len(args)):
        num = args[i]
        remain = target - num
        # 如果当前元素和tmp中的元素之和不等于target,把当前元素存储到tmp中,用于后续比较
        if remain not in tmp:
            tmp[num] = i
        # 如果当前元素和tmp中的元素之和等于target,把tmp中匹配到的元素移除,并且把当前匹配到数据添加到matches
        else:
            tmp.pop(remain)
            matches.append([remain, num])
    # 缺点:循环结束之后tmp不一定为{}空字典
    # print(tmp)
    return matches

# 方法3: 嵌套循环,时间复杂度:O(N^2),N的2次方。
# 难点:怎么保证不重复使用数据?
def matchTarget3(args, target):
    matches = []
    if not isinstance(args, list):
        print("必须传递数组类型")
        return matches

    if len(args) < 2:
        return matches

    length = len(args)
    for i in range(length):
        j = i+1
        print("-------, i:j", i, j)
        for j in range(length):
            if i != j and args[i] + args[j] == target:
                matches.append([args[i], args[j]])
        return matches


print(matchTarget2([5,6,5], 11))      # [[5, 6]]
print(matchTarget2([5,6,5,6], 11))    # [[5, 6], [5, 6]]
# print(matchTarget2([4,5,3,6], 9))    # [[4, 5], [3, 6]]

3、求数组中的第二大的元素

  • 注意点1:第二大的数需要考虑最大数有重复的情况,不要被套路了。如果最大数有重复的话就不能直接sort()排序之后再取倒数第二个的值了。
  • 解决思路:列表元素去重+排序+取值

1、使用set()集合去重

arr = [1, 2, 5, 6, 4, 6]
b = set(arr)
sorted(b)[-2]        # 返回第二大的元素,5

2、使用numpy包去重

import numpy
arr = [1, 2, 5, 6, 4, 6]
b = numpy.unique(arr)        # array([1, 2, 4, 5, 6]),不会改变原数组
sorted(b)[-2]                    # 返回第二大的元素,5

4、计算数组元素重复次数

1、使用内置list.count(i)函数

a = [1,1,2,3,3,3]
b = set(a)      # (1,2,3)
for i in b:
    a.count(i)

2、使用Python字典
Python字典是一种键值对的数据类型,可以用来统计元素出现的次数。具体方法是将每个元素作为字典的键,出现的次数作为字典的值。例如:

a = [1, 2, 3, 4, 3, 2, 1]
d = {}
for i in a:
    if i in d:
        d[i] += 1
    else:
        d[i] = 1
print(d)           # 输出{1: 2, 2: 2, 3: 2, 4: 1}

你可能感兴趣的:(python常见算法题)