zoukankan      html  css  js  c++  java
  • python 数据结构和算法

    # heapq模块(堆排序):从列表中找出最大的或最小的N个元素
    import heapq
    list1 = [34, 25, 12, 99, 87, 63, 58, 78, 88, 92]
    list2 = [
        {'name': 'IBM', 'shares': 100, 'price': 91.1},
        {'name': 'AAPL', 'shares': 50, 'price': 543.22},
        {'name': 'FB', 'shares': 200, 'price': 21.09},
    ]
    print(heapq.nlargest(3, list1))   # nsmallest
    print(heapq.nlargest(2, list2, key=lambda x: x['price']))
    
    ################################################################################################
    import itertools
    itertools.permutations('ABCD')      # 产生ABCD的全排列
    itertools.combinations('ABCDE', 3)  # 产生ABCDE的五选三组合
    itertools.product('ABCD', '123')    # 产生ABCD和123的笛卡尔积
    itertools.cycle(('A', 'B', 'C'))    # 产生ABC的无限循环序列
    
    
    # collections模块常用的工具类:
    # namedtuple:命令元组,它是一个类工厂,接受类型的名称和属性列表来创建一个类。
    # deque:双端队列,是列表的替代实现。Python中列表底层是基于数组来实现的,而deque底层是双向链表,因此当你需要在头尾添加和删除元素是,deque会表现出更好的性能,渐近时间复杂度为O(1)。
    # Counter:dict子类,键是元素,值是元素的计数,它的most_common()方法获取出现频率最高的元素。Counter和dict的继承关系值得商榷的,按照CARP原则,Counter跟dict的关系应该设计为关联关系更为合理。
    # OrderedDict:dict的子类,它记录键值对插入的顺序,看起来既有字典的行为,也有链表的行为。
    # defaultdict:类似于字典类型,但是可通过默认的工厂函数来获得键对应的默认值,相比字典中的setdefault()方法,这种做法更加高效。
    
    from collections import Counter
    words = [
        'look', 'into', 'my', 'eyes','the', 'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into', 'my', 'eyes', "you're", 'under'
    ]
    counter = Counter(words)
    print(counter.most_common(3))   # 找出序列中出现次数最多的元素

     

    数据结构和算法

    • 算法:解决问题的方法和步骤

    • 评价算法的好坏:渐近时间复杂度和渐近空间复杂度。

    • 渐近时间复杂度的大O标记:

      •  - 常量时间复杂度 - 布隆过滤器 / 哈希存储
      •  - 对数时间复杂度 - 折半查找(二分查找)
      •  - 线性时间复杂度 - 顺序查找 / 计数排序
      •  - 对数线性时间复杂度 - 高级排序算法(归并排序、快速排序)
      •  - 平方时间复杂度 - 简单排序算法(选择排序、插入排序、冒泡排序)
      •  - 立方时间复杂度 - Floyd算法 / 矩阵乘法运算
      •  - 几何级数时间复杂度 - 汉诺塔
      •  - 阶乘时间复杂度 - 旅行经销商问题 - NPC

    常用算法:

    • 穷举法 - 又称为暴力破解法,对所有的可能性进行验证,直到找到正确答案。
    • 贪婪法 - 在对问题求解时,总是做出在当前看来
    • 最好的选择,不追求最优解,快速找到满意解。
    • 分治法 - 把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题,直到可以直接求解的程度,最后将子问题的解进行合并得到原问题的解。
    • 回溯法 - 回溯法又称为试探法,按选优条件向前搜索,当搜索到某一步发现原先选择并不优或达不到目标时,就退回一步重新选择。
    • 动态规划 - 基本思想也是将待求解问题分解成若干个子问题,先求解并保存这些子问题的解,避免产生大量的重复运算。

    排序算法(选择、冒泡和归并)和查找算法(顺序和折半)

    def select_sort(items, comp=lambda x, y: x < y):
        """简单选择排序"""
        items = items[:]
        for i in range(len(items) - 1):
            min_index = i
            for j in range(i + 1, len(items)):
                if comp(items[j], items[min_index]):
                    min_index = j
            items[i], items[min_index] = items[min_index], items[i]
        return items
    def bubble_sort(items, comp=lambda x, y: x > y): """冒泡排序""" items = items[:] for i in range(len(items) - 1): swapped = False for j in range(i, len(items) - 1 - i): if comp(items[j], items[j + 1]): items[j], items[j + 1] = items[j + 1], items[j] swapped = True if not swapped: break return items
    def bubble_sort(items, comp=lambda x, y: x > y): """搅拌排序(冒泡排序升级版)""" items = items[:] for i in range(len(items) - 1): swapped = False for j in range(i, len(items) - 1 - i): if comp(items[j], items[j + 1]): items[j], items[j + 1] = items[j + 1], items[j] swapped = True if swapped: swapped = False for j in range(len(items) - 2 - i, i, -1): if comp(items[j - 1], items[j]): items[j], items[j - 1] = items[j - 1], items[j] swapped = True if not swapped: break return items

    def merge(items1, items2, comp=lambda x, y: x < y): """合并(将两个有序的列表合并成一个有序的列表)""" items = [] index1, index2 = 0, 0 while index1 < len(items1) and index2 < len(items2): if comp(items1[index1], items2[index2]): items.append(items1[index1]) index1 += 1 else: items.append(items2[index2]) index2 += 1 items += items1[index1:] items += items2[index2:] return items def merge_sort(items, comp=lambda x, y: x < y): return _merge_sort(list(items), comp) def _merge_sort(items, comp): """归并排序""" if len(items) < 2: return items mid = len(items) // 2 left = _merge_sort(items[:mid], comp) right = _merge_sort(items[mid:], comp) return merge(left, right, comp)

    def seq_search(items, key): """顺序查找""" for index, item in enumerate(items): if item == key: return index return -1
    def bin_search(items, key): """折半查找""" start, end = 0, len(items) - 1 while start <= end: mid = (start + end) // 2 if key > items[mid]: start = mid + 1 elif key < items[mid]: end = mid - 1 else: return mid return -1

     贪婪

    回溯法例子:骑士巡逻

    动态规划例子:子列表元素之和的最大值。

    def main():
        items = list(map(int, input().split()))
        overall = partial = items[0]
        for i in range(1, len(items)):
            partial = max(items[i], partial + items[i])
            overall = max(partial, overall)
        print(overall)

    分治法:快速排序

    """快速排序 - 选择枢轴对元素进行划分,左边都比枢轴小右边都比枢轴大"""
    def quick_sort(items, comp=lambda x, y: x <= y):
        items = list(items)[:]
        _quick_sort(items, 0, len(items) - 1, comp)
        return items
    
    def _quick_sort(items, start, end, comp):
        if start < end:
            pos = _partition(items, start, end, comp)
            _quick_sort(items, start, pos - 1, comp)
            _quick_sort(items, pos + 1, end, comp)
    
    def _partition(items, start, end, comp):
        pivot = items[end]
        i = start - 1
        for j in range(start, end):
            if comp(items[j], pivot):
                i += 1
                items[i], items[j] = items[j], items[i]
        items[i + 1], items[end] = items[end], items[i + 1]
        return i + 1

     

  • 相关阅读:
    置换群
    背包问题
    并查集
    链式前向星
    一个简单的金额平均分配函数(C#版)
    EasyUI ComboGrid的绑定,上下键和回车事件,输入条件查询
    Oracle表解锁语句
    如何将两个json合并成一个
    textbox只能输入数字或中文的常用正则表达式和验证方法
    C#注册表的读,写,删除,查找
  • 原文地址:https://www.cnblogs.com/bsszds930/p/12910643.html
Copyright © 2011-2022 走看看