返回

六种算法思维,让你成为超级程序员

Android

  1. 分治法

分治法是一种将问题分解成更小的子问题,然后递归地解决这些子问题的算法设计技术。分治法通常用于解决具有递归性质的问题,例如归并排序、快速排序和二分查找。

def merge_sort(arr):
    if len(arr) <= 1:
        return arr

    mid = len(arr) // 2
    left_half = merge_sort(arr[:mid])
    right_half = merge_sort(arr[mid:])

    return merge(left_half, right_half)

def merge(left, right):
    merged = []
    left_index = 0
    right_index = 0

    while left_index < len(left) and right_index < len(right):
        if left[left_index] <= right[right_index]:
            merged.append(left[left_index])
            left_index += 1
        else:
            merged.append(right[right_index])
            right_index += 1

    merged.extend(left[left_index:])
    merged.extend(right[right_index:])

    return merged

2. 动态规划

动态规划是一种通过将问题分解成重叠子问题,然后将这些子问题的解决方案存储起来,从而避免重复计算的算法设计技术。动态规划通常用于解决具有最优子结构和最长公共子序列的问题,例如背包问题、最长公共子序列问题和最长公共子串问题。

def knapsack(items, capacity):
    dp = [[0] * (capacity + 1) for _ in range(len(items) + 1)]

    for i in range(1, len(items) + 1):
        weight, value = items[i - 1]
        for j in range(1, capacity + 1):
            if weight <= j:
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight] + value)
            else:
                dp[i][j] = dp[i - 1][j]

    return dp[len(items)][capacity]

3. 贪心算法

贪心算法是一种通过在每个步骤中做出局部最优决策,从而得到全局最优解的算法设计技术。贪心算法通常用于解决具有贪心性质的问题,例如最小生成树问题、最短路径问题和作业调度问题。

def prim(graph):
    mst = []
    visited = set()
    current_node = 0
    visited.add(current_node)

    while len(visited) < len(graph):
        min_edge = (float('inf'), -1, -1)
        for u in visited:
            for v, weight in graph[u]:
                if v not in visited and weight < min_edge[0]:
                    min_edge = (weight, u, v)

        mst.append(min_edge)
        visited.add(min_edge[2])

    return mst

4. 回溯法

回溯法是一种通过枚举所有可能的解决方案,然后回溯到上一个状态并尝试其他解决方案的算法设计技术。回溯法通常用于解决具有回溯性质的问题,例如八皇后问题、走迷宫问题和图着色问题。

def n_queens(n):
    board = [['.' for _ in range(n)] for _ in range(n)]
    result = []

    def is_safe(board, row, col):
        for i in range(row):
            if board[i][col] == 'Q':
                return False
        for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
            if board[i][j] == 'Q':
                return False
        for i, j in zip(range(row, -1, -1), range(col, n)):
            if board[i][j] == 'Q':
                return False
        return True

    def solve(board, row):
        if row == n:
            result.append([[''.join(row) for row in board]])
            return

        for col in range(n):
            if is_safe(board, row, col):
                board[row][col] = 'Q'
                solve(board, row + 1)
                board[row][col] = '.'

    solve(board, 0)
    return result

5. 分支限界法

分支限界法是一种通过将问题分解成更小的子问题,然后对这些子问题进行枚举和剪枝,从而得到最优解的算法设计技术。分支限界法通常用于解决具有最优子结构和有界的问题,例如旅行商问题、装箱问题和背包问题。

def traveling_salesman(graph):
    min_tour = float('inf')
    min_tour_path = []

    def tsp(current_city, visited, cost):
        nonlocal min_tour
        nonlocal min_tour_path

        if len(visited) == len(graph):
            if cost + graph[current_city][0] < min_tour:
                min_tour = cost + graph[current_city][0]
                min_tour_path = visited[:]
            return

        for next_city in range(len(graph)):
            if next_city not in visited:
                visited.append(next_city)
                tsp(next_city, visited, cost + graph[current_city][next_city])
                visited.pop()

    tsp(0, [0], 0)
    return min_tour_path

6. 近似算法

近似算法是一种通过牺牲一定程度的准确性来换取更快的运行时间的算法设计技术。近似算法通常用于解决具有 NP 完全性或 NP 困难性