作者: admin2025

  • 用C语言给出冒泡算法

    当然可以。冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复进行的,直到没有再需要交换的元素为止。

    以下是使用C语言实现的冒泡排序算法的代码示例:

    #include

    // 函数声明 void bubbleSort(int arr[], int n); void swap(int xp, int yp); void printArray(int arr[], int size);

    int main() { int arr[] = {64, 34, 25, 12, 22, 11, 90}; int n = sizeof(arr)/sizeof(arr[0]);

    printf("原始数组: \n");
    printArray(arr, n);
    
    bubbleSort(arr, n);
    
    printf("排序后的数组: \n");
    printArray(arr, n);
    
    return 0;

    }

    // 冒泡排序函数 void bubbleSort(int arr[], int n) { int i, j; for (i = 0; i < n-1; i++) { // 最后i个元素已经是排序好的 for (j = 0; j < n-i-1; j++) { if (arr[j] > arr[j+1]) { swap(&arr[j], &arr[j+1]); } } } }

    // 用于交换两个元素的函数 void swap(int xp, int yp) { int temp = xp; xp = yp; yp = temp; }

    // 打印数组的函数 void printArray(int arr[], int size) { int i; for (i=0; i < size; i++) printf("%d ", arr[i]); printf("\n"); }

    代码解释:

    1. bubbleSort 函数
      • 这个函数实现了冒泡排序算法。
      • 外层循环 for (i = 0; i < n-1; i++) 控制排序的趟数。
      • 内层循环 for (j = 0; j < n-i-1; j++) 用于在每一趟中比较和交换元素。
      • 如果当前元素 arr[j] 大于后一个元素 arr[j+1],则调用 swap 函数交换它们。
    2. swap 函数
      • 这个函数用于交换两个整数的值。
      • 通过传递指针来实现交换,避免了值的复制。
    3. printArray 函数
      • 这个函数用于打印数组中的元素。
    4. main 函数
      • 定义了一个待排序的数组 arr
      • 计算数组的大小 n
      • 调用 bubbleSort 函数对数组进行排序。
      • 在排序前后分别调用 printArray 函数打印数组。

    运行结果:

    运行上述代码后,你将看到原始数组和排序后的数组输出。

    希望这个示例对你有帮助!如果有任何问题,欢迎继续提问。

  • The Maze III,LeetCode,499

    题目描述:

    The Maze III 是 LeetCode 上的一道中等难度的题目,编号为 499。题目描述如下:

    有一个迷宫,由 m x n 的二维网格表示。网格中有空地(用 表示)和墙壁(用 1 表示)。此外,迷宫中有一个球,球的初始位置为 (startrow, startcol),目标位置为 (goalrow, goalcol)

    球可以沿着四个方向(上、下、左、右)滚动,但每次滚动都会一直滚到遇到墙壁或边界为止。你需要找到球从初始位置滚到目标位置的最短路径,并返回这条路径。如果有多条最短路径,返回字典序最小的那条。

    输入:

    • maze: 迷宫的二维数组
    • startrow, startcol: 球的初始位置
    • goalrow, goalcol: 目标位置

    输出:

    • 字符串,表示球从初始位置到目标位置的最短路径,路径由 'u'(上)、'd'(下)、'l'(左)、'r'(右)组成。

    示例:

    输入: maze = [ [0, 0, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 1, 0], [1, 1, 0, 1, 1], [0, 0, 0, 0, 0] ] startrow = 0, startcol = 4 goalrow = 4, goalcol = 4

    输出: "dldr"

    解题思路:

    1. BFS(广度优先搜索)
      • 使用 BFS 来遍历迷宫,记录每个位置到达的最短路径和路径长度。
      • 使用优先队列(最小堆)来保证字典序最小的路径优先被处理。
    2. DFS(深度优先搜索)
      • 使用 DFS 来遍历迷宫,记录每个位置到达的最短路径和路径长度。
      • 需要使用额外的数据结构来记录已访问的位置和路径长度,以避免重复遍历。
    3. Dijkstra 算法
      • 使用 Dijkstra 算法来找到最短路径,同时维护路径的字典序。

    具体实现步骤(BFS 方法):

    1. 初始化一个优先队列,存储 (路径长度, 当前位置, 路径) 的三元组。
    2. 将初始位置 (0, startrow, startcol, "") 加入优先队列。
    3. 使用一个字典 visited 来记录每个位置的最短路径长度和字典序最小的路径。
    4. 从优先队列中取出当前状态,更新 visited
    5. 沿四个方向滚动球,计算新的位置和路径,如果新位置更优,则加入优先队列。
    6. 重复步骤 4 和 5,直到找到目标位置。

    Python 代码示例:

    from heapq import heappop, heappush from collections import defaultdict

    def shortestDistance(maze, startrow, startcol, goalrow, goalcol): m, n = len(maze), len(maze[0]) directions = [(-1, 0, 'u'), (1, 0, 'd'), (0, -1, 'l'), (0, 1, 'r')] visited = defaultdict(lambda: float('inf')) pq = [(0, startrow, startcol, "")]

    while pq:
        dist, x, y, path = heappop(pq)
        if (x, y) == (goalrow, goalcol):
            return path
        if dist > visited[(x, y)]:
            continue
        visited[(x, y)] = dist
    
        for dx, dy, d in directions:
            nx, ny, step = x, y, 0
            while 0 <= nx + dx < m and 0 <= ny + dy < n and maze[nx + dx][ny + dy] == 0:
                nx += dx
                ny += dy
                step += 1
            if dist + step < visited[(nx, ny)]:
                visited[(nx, ny)] = dist + step
                heappush(pq, (dist + step, nx, ny, path + d))
    
    return ""

    示例输入

    maze = [ [0, 0, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 1, 0], [1, 1, 0, 1, 1], [0, 0, 0, 0, 0] ] startrow = 0 startcol = 4 goalrow = 4 goalcol = 4

    调用函数

    print(shortestDistance(maze, startrow, startcol, goalrow, goalcol)) # 输出: "dldr"

    解释:

    • 使用优先队列 pq 来存储当前的状态 (路径长度, 当前位置, 路径),保证字典序最小的路径优先被处理。
    • 使用 visited 字典来记录每个位置的最短路径长度,避免重复遍历。
    • 沿四个方向滚动球,计算新的位置和路径,如果新位置更优,则加入优先队列。
    • 最终找到目标位置时,返回对应的路径。

    希望这个详细的解答能帮助你理解并解决 The Maze III 这道题目。如果有任何进一步的问题,欢迎继续提问!

  • Diagonal Traverse,LeetCode,498

    题目描述:

    给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素。

    示例:

    输入: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]

    输出: [1,2,4,7,5,3,6,8,9]

    解释:

    解题思路:

    1. 初始化
      • 创建一个结果列表 result 用于存储遍历的元素。
      • 设置初始位置 (i, j)(0, 0),即矩阵的左上角。
      • 设置方向标志 direction,初始为 1 表示向右上遍历,-1 表示向左下遍历。
    2. 遍历矩阵
      • 使用一个循环,直到遍历完所有元素(即遍历了 M x N 次)。
      • 在每次循环中,将当前元素添加到 result 列表中。
      • 根据当前方向 direction 更新位置 (i, j)
        • 如果 direction1(向右上),则 i1j1
        • 如果 direction-1(向左下),则 i1j1
      • 检查更新后的位置 (i, j) 是否越界:
        • 如果 i 越界(小于 或大于 M-1),则调整 i 并改变方向。
        • 如果 j 越界(小于 或大于 N-1),则调整 j 并改变方向。
    3. 返回结果
      • 遍历完成后,返回 result 列表。

    代码实现(Python):

    class Solution: def findDiagonalOrder(self, matrix): if not matrix or not matrix[0]: return []

        M, N = len(matrix), len(matrix[0])
        result = []
        i, j = 0, 0
        direction = 1
    
        for _ in range(M * N):
            result.append(matrix[i][j])
    
            if direction == 1:
                new_i, new_j = i - 1, j + 1
                if new_i < 0 or new_j >= N:
                    direction = -1
                    if new_j >= N:
                        i += 1
                    else:
                        j += 1
                else:
                    i, j = new_i, new_j
            else:
                new_i, new_j = i + 1, j - 1
                if new_i >= M or new_j < 0:
                    direction = 1
                    if new_i >= M:
                        j += 1
                    else:
                        i += 1
                else:
                    i, j = new_i, new_j
    
        return result

    解释:

    • 初始化:检查矩阵是否为空,获取矩阵的行数 M 和列数 N,初始化结果列表 result,起始位置 (i, j) 和方向 direction
    • 遍历矩阵:使用一个循环遍历所有元素,根据当前方向更新位置,并在越界时调整位置和方向。
    • 返回结果:遍历完成后,返回结果列表 result

    这个解法的时间复杂度为 O(M * N),空间复杂度为 O(1)(不包括结果列表的空间)。

    希望这个详细的解释和代码实现能帮助你理解并解决 LeetCode 498 题“对角线遍历”。如果有任何进一步的问题,欢迎继续提问!

  • Random Point in Non-overlapping Rectangles,LeetCode,497

    LeetCode 497题 “Random Point in Non-overlapping Rectangles” 是一个中等难度的题目,主要考察的是随机算法和几何知识。题目要求在一个由多个不重叠矩形组成的区域中随机选取一个点。

    题目描述

    给定一个由多个不重叠矩形组成的列表 rects,每个矩形由其左下角和右上角的坐标表示,即 rects[i] = [x1, y1, x2, y2],其中 (x1, y1) 是左下角的坐标,(x2, y2) 是右上角的坐标。

    你需要实现一个 Solution 类,包含以下方法:

    1. Solution(rects):用给定的矩形列表初始化对象。
    2. pick():随机选取一个点,返回这个点的坐标。

    示例

    输入: ["Solution", "pick", "pick", "pick"] [[[[1,1,5,5]]], [], [], []] 输出: [null, [4,1], [4,1], [3,3]]

    解题思路

    1. 初始化(Solution 构造函数)
      • 计算每个矩形的面积。
      • 累积每个矩形的面积,以便后续使用。
    2. 随机选取点(pick 方法)
      • 根据累积的面积随机选择一个矩形。
      • 在选中的矩形内随机选择一个点。

    详细实现

    import random

    class Solution: def init(self, rects): self.rects = rects self.areas = [] self.total_area = 0

        # 计算每个矩形的面积并累积
        for x1, y1, x2, y2 in rects:
            area = (x2 - x1 + 1) * (y2 - y1 + 1)
            self.total_area += area
            self.areas.append(self.total_area)
    
    def pick(self):
        # 随机选择一个点
        rand_area = random.randint(1, self.total_area)
    
        # 找到包含该随机点的矩形
        idx = 0
        while rand_area > self.areas[idx]:
            idx += 1
    
        # 在选中的矩形内随机选择一个点
        x1, y1, x2, y2 = self.rects[idx]
        rand_x = random.randint(x1, x2)
        rand_y = random.randint(y1, y2)
    
        return [rand_x, rand_y]

    示例使用

    rects = [[1,1,5,5]]

    solution = Solution(rects)

    print(solution.pick()) # 输出可能是 [4,1], [3,3] 等

    解释

    1. 构造函数 __init__
      • self.rects 存储输入的矩形列表。
      • self.areas 存储每个矩形的累积面积。
      • self.total_area 存储所有矩形的总面积。
    2. pick 方法
      • rand_area 是一个在 [1, total_area] 范围内的随机数。
      • 通过遍历 self.areas 找到包含 rand_area 的矩形。
      • 在选中的矩形内随机生成一个点的坐标。

    复杂度分析

    • 时间复杂度
      • 构造函数:O(N),其中 N 是矩形的数量。
      • pick 方法:O(N),因为需要遍历 self.areas 找到对应的矩形。
    • 空间复杂度O(N),用于存储矩形的累积面积。

    这个实现确保了每个点被选中的概率与其所在矩形的面积成正比,符合题目要求。

  • Next Greater Element I,LeetCode,496

    题目描述:

    给定两个没有重复元素的数组 nums1nums2 ,其中 nums1nums2 的子集。找到 nums1 中每个元素在 nums2 中的下一个比其大的值。

    nums1 中的数字在 nums2 中是唯一的,但 nums2 中的数字不一定在 nums1 中。

    示例:

    输入: nums1 = [4,1,2], nums2 = [1,3,4,2].

    输出: [-1,3,-1]

    解释: 对于num1中的数字4,你无法在 num2 中找到一个更大的数字,因此输出 -1。 对于num1中的数字1,num2 中数字1右边的下一个较大数字是 3。 对于num1中的数字2,你无法在 num2 中找到一个更大的数字,因此输出 -1。

    解题思路:

    1. 单调栈:使用单调栈来解决这个问题。单调栈是一种特殊的栈,用于处理序列中元素的前驱问题和后继问题。在这个问题中,我们可以利用单调栈找到 nums2 中每个元素的下一个更大的元素。
    2. 哈希表:使用哈希表来存储 nums2 中每个元素的下一个更大的元素,以便快速查找。

    具体步骤:

    1. 构建单调栈和哈希表
      • 遍历 nums2,使用一个栈来维护一个单调递减的序列。
      • 对于每个元素 num
        • 如果栈不为空且当前元素 num 大于栈顶元素,说明找到了栈顶元素的下一个更大的元素,将其弹出并记录到哈希表中。
        • 将当前元素 num 压入栈中。
    2. 查找结果
      • 遍历 nums1,对于每个元素,直接在哈希表中查找其下一个更大的元素。

    代码实现:

    def nextGreaterElement(nums1, nums2):

    单调栈和哈希表

    stack = []
    next_greater = {}
    
    # 遍历nums2,构建单调栈和哈希表
    for num in nums2:
        while stack and num > stack[-1]:
            next_greater[stack.pop()] = num
        stack.append(num)
    
    # 处理栈中剩余的元素,这些元素没有下一个更大的元素
    while stack:
        next_greater[stack.pop()] = -1
    
    # 遍历nums1,查找每个元素的下一个更大的元素
    result = [next_greater[num] for num in nums1]
    
    return result

    示例

    nums1 = [4,1,2] nums2 = [1,3,4,2] print(nextGreaterElement(nums1, nums2)) # 输出: [-1, 3, -1]

    复杂度分析:

    • 时间复杂度:O(n + m),其中 n 是 nums2 的长度,m 是 nums1 的长度。我们首先遍历 nums2 构建单调栈和哈希表,然后遍历 nums1 查找结果。
    • 空间复杂度:O(n),主要用于存储单调栈和哈希表。

    总结:

    通过单调栈和哈希表的结合,我们可以高效地解决这个问题。单调栈帮助我们找到每个元素的下一个更大的元素,而哈希表则用于快速查找结果。这种方法在处理类似的前驱和后继问题时非常有效。

  • Teemo Attacking,LeetCode,495

    好的,我们来详细解析一下 LeetCode 上的 495 号问题:Teemo Attacking。

    题目描述

    在《英雄联盟》的世界中,有一个叫 Teemo 的英雄,他的技能可以让敌人中毒。现在给定一个数组 timeSeries,其中 timeSeries[i] 表示 Teemo 在第 i 秒时对敌人发动攻击的时间点。每次攻击会让敌人中毒 duration 秒。如果 Teemo 在敌人中毒期间再次攻击,中毒时间会重新计算。

    你需要计算敌人总共中毒的时间。

    示例

    示例 1:

    输入: timeSeries = [1,4], duration = 2 输出: 4 解释: 在第 1 秒开始中毒,持续 2 秒,总共中毒 2 秒。 在第 4 秒再次攻击,重新计算中毒时间,持续 2 秒,总共中毒 4 秒。

    示例 2:

    输入: timeSeries = [1,2], duration = 2 输出: 3 解释: 在第 1 秒开始中毒,持续 2 秒。 在第 2 秒再次攻击,重新计算中毒时间,但只多中毒 1 秒,因为第 1 秒的攻击还在持续。

    解题思路

    1. 初始化变量
      • total 用于记录总的中毒时间。
      • last 用于记录上一次攻击的时间点。
    2. 遍历攻击时间点
      • 对于每个攻击时间点 t
        • 如果当前攻击时间点 t 与上一次攻击时间点 last 的间隔大于或等于 duration,说明上一次中毒已经结束,直接加上 duration
        • 如果间隔小于 duration,说明上一次中毒还未结束,只加上两次攻击之间的间隔时间 t - last
        • 更新 last 为当前攻击时间点 t
    3. 处理最后一次攻击
      • 最后一次攻击后,无论是否有新的攻击,都需要加上 duration 秒的中毒时间。

    代码实现

    class Solution: def findPoisonedDuration(self, timeSeries, duration): if not timeSeries: return 0

        total = 0
        last = timeSeries[0]
    
        for t in timeSeries[1:]:
            if t - last >= duration:
                total += duration
            else:
                total += t - last
            last = t
    
        total += duration  # 处理最后一次攻击
        return total

    复杂度分析

    • 时间复杂度:O(n),其中 n 是 timeSeries 的长度,因为我们只需要遍历一次数组。
    • 空间复杂度:O(1),因为我们只使用了常数级别的额外空间。

    总结

    这个问题的核心在于正确处理每次攻击的中毒时间,特别是当两次攻击间隔小于 duration 时,需要仔细计算实际增加的中毒时间。通过遍历攻击时间点并累加中毒时间,我们可以高效地解决这个问题。

    希望这个详细的解析对你有所帮助!如果有任何进一步的问题,欢迎继续提问。

  • Target Sum,LeetCode,494

    题目描述(LeetCode 494. Target Sum)

    给你一个整数数组 nums 和一个整数 target

    向数组中的每个整数前添加 '+''-' ,然后串联起所有整数,可以构造一个 表达式

    • 例如,数组 [1, 2, 3]target = 3 可以构造出以下表达式:
      • 1 + 2 + 3 = 6
      • +1 - 2 + 3 = 2
      • +1 + 2 - 3 = 0
      • -1 + 2 + 3 = 4
  • Reverse Pairs,LeetCode,493

    LeetCode 493题 “Reverse Pairs” 是一个中等难度的题目,主要考察的是归并排序的应用以及如何处理逆序对的问题。下面我将详细解释题目的要求、解题思路以及具体的代码实现。

    题目描述

    给定一个整数数组 nums,返回数组中的逆序对的数量。逆序对的定义是:对于数组中的两个元素 nums[i]nums[j],如果满足 i < jnums[i] > 2 * nums[j],则 (nums[i], nums[j]) 是一个逆序对。

    解题思路

    这个问题可以通过暴力枚举来解决,但时间复杂度会达到 O(n^2),对于大数据集来说效率太低。更好的方法是使用归并排序的思想,时间复杂度可以优化到 O(n log n)。

    归并排序的过程中,当我们合并两个有序数组时,可以同时统计逆序对的数量。具体步骤如下:

    1. 分割数组:将数组递归地分割成更小的数组,直到每个数组只有一个元素。
    2. 合并数组:在合并两个有序数组的过程中,统计逆序对的数量。
    3. 统计逆序对:在合并时,如果左数组的当前元素大于右数组的当前元素的2倍,那么左数组中当前元素及其后面的所有元素都与右数组的当前元素构成逆序对。

    代码实现

    以下是使用归并排序思想的 Python 代码实现:

    class Solution: def reversePairs(self, nums): def mergeSort(l, r): if l >= r: return 0

            mid = (l + r) // 2
            count = mergeSort(l, mid) + mergeSort(mid + 1, r)
    
            # 统计逆序对
            j = mid + 1
            for i in range(l, mid + 1):
                while j <= r and nums[i] > 2 * nums[j]:
                    j += 1
                count += j - (mid + 1)
    
            # 合并两个有序数组
            nums[l:r+1] = sorted(nums[l:r+1])
            return count
    
        return mergeSort(0, len(nums) - 1)

    示例

    sol = Solution() print(sol.reversePairs([1, 3, 2, 3, 1])) # 输出: 2

    详细解释

    1. mergeSort 函数
      • 这是一个递归函数,用于对数组进行归并排序并统计逆序对。
      • lr 分别是当前子数组的左右边界。
      • 首先递归地对左右子数组进行排序并统计逆序对。
      • 然后在合并前,通过双指针方法统计逆序对的数量。
      • 最后合并两个有序子数组。
    2. 统计逆序对
      • 使用两个指针 iji 遍历左子数组,j 遍历右子数组。
      • 如果 nums[i] > 2 * nums[j],则 j 向右移动,直到不满足条件。
      • 此时,j - (mid + 1) 就是与 nums[i] 构成逆序对的右子数组元素的数量。
    3. 合并数组
      • 使用 Python 的内置 sorted 函数合并两个有序子数组。

    复杂度分析

    • 时间复杂度:O(n log n),归并排序的时间复杂度。
    • 空间复杂度:O(n),递归调用栈和临时数组的空间。

    通过这种方法,我们能够高效地解决 Reverse Pairs 问题。希望这个详细的解释和代码实现对你有所帮助!如果有任何进一步的问题,欢迎继续提问。

  • Construct the Rectangle,LeetCode,492

    LeetCode 492题 “Construct the Rectangle” 是一个数学问题,要求我们为一个给定的面积找到最接近的矩形尺寸(长和宽)。具体来说,我们需要找到一个矩形的长度 L 和宽度 W,使得 L * W = area,并且 L 和 W 的差值尽可能小。

    题目描述

    给定一个整数 area,找到三个整数 LW,使得:

    1. L * W = area
    2. L >= W
    3. L 和 W 的差值尽可能小

    示例

    输入: area = 4 输出: [2, 2] 解释: 2 * 2 = 4 且 2 - 2 = 0,差值最小。

    输入: area = 37 输出: [37, 1] 解释: 37 * 1 = 37 且 37 - 1 = 36,这是唯一可能的组合。

    解题思路

    1. 从平方根开始:为了使 L 和 W 的差值尽可能小,我们可以从 sqrt(area) 开始向下查找。因为平方根处的值是最接近的两个因数。
    2. 遍历因数:从 sqrt(area) 开始向下遍历,找到第一个能整除 area 的数,这个数作为宽度 W,对应的商作为长度 L。
    3. 返回结果:返回 [L, W]

    代码实现

    以下是 Python 的实现代码:

    import math

    def constructRectangle(area):

    从平方根开始向下遍历

    for w in range(int(math.sqrt(area)), 0, -1):
        if area % w == 0:
            return [area // w, w]

    示例

    print(constructRectangle(4)) # 输出: [2, 2] print(constructRectangle(37)) # 输出: [37, 1]

    详细解释

    1. 导入 math 库:用于计算平方根。
    2. 遍历范围range(int(math.sqrt(area)), 0, -1)sqrt(area) 向下遍历到 1。
    3. 判断整除if area % w == 0 检查当前宽度 w 是否能整除 area
    4. 返回结果:如果找到符合条件的宽度 w,则返回 [area // w, w],其中 area // w 是长度 L。

    复杂度分析

    • 时间复杂度:O(sqrt(area)),因为我们最多遍历到 sqrt(area)
    • 空间复杂度:O(1),只使用了常数级别的额外空间。

    这种方法高效且直观,能够很好地解决题目要求。希望这个解释对你有帮助!如果有其他问题,欢迎继续提问。

  • Increasing Subsequences,LeetCode,491

    LeetCode 491题 “Increasing Subsequences” 是一个中等难度的题目,主要考察的是深度优先搜索(DFS)和回溯算法。题目要求找到给定数组中的所有递增子序列。

    题目描述

    给定一个整型数组,你的任务是找到所有的递增子序列,递增子序列的长度至少为2。

    示例

    输入: [4, 6, 7, 7] 输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]

    解题思路

    1. 深度优先搜索(DFS):通过递归的方式遍历所有可能的子序列。
    2. 回溯:在递归过程中,如果当前子序列不再满足递增条件,则回溯到上一步。
    3. 去重:使用集合来避免重复的子序列。

    详细步骤

    1. 初始化:定义一个结果集 res 和一个临时路径 path
    2. 递归函数:定义一个递归函数 dfs(start),从数组的 start 位置开始搜索。
    3. 递归终止条件:当遍历到数组末尾时,检查 path 的长度是否大于1,如果是则加入结果集。
    4. 递归逻辑
      • 遍历从 start 到数组末尾的所有元素。
      • 如果当前元素可以加入 path(即当前元素大于 path 的最后一个元素或者 path 为空),则将其加入 path 并继续递归。
      • 递归结束后,回溯,即从 path 中移除当前元素。

    代码实现

    def findSubsequences(nums): def dfs(start, path): if len(path) > 1: res.append(path[:]) used = set() for i in range(start, len(nums)): if nums[i] in used: continue if not path or nums[i] >= path[-1]: used.add(nums[i]) dfs(i + 1, path + [nums[i]])

    res = []
    dfs(0, [])
    return res

    示例

    nums = [4, 6, 7, 7] print(findSubsequences(nums))

    代码解释

    1. findSubsequences 函数:主函数,初始化结果集 res 并调用 dfs 函数。
    2. dfs 函数
      • start:当前开始搜索的位置。
      • path:当前递增子序列。
      • used:用于去重的集合,避免在同一层递归中使用相同的元素。
    3. 递归逻辑
      • 遍历从 start 到数组末尾的所有元素。
      • 如果当前元素未在当前层使用过,并且可以加入 path,则加入 path 并继续递归。
      • 递归结束后,回溯。

    复杂度分析

    • 时间复杂度:O(2^N),在最坏情况下,每个元素都有两种选择(加入或不加入子序列)。
    • 空间复杂度:O(N),递归栈的深度最多为 N。

    通过上述步骤和代码实现,可以有效地找到数组中的所有递增子序列。希望这个详细的解答对你有所帮助!如果有任何进一步的问题,欢迎继续提问。