【LeetCode】46. 排列

本文介绍了两种求解整数全排列的方法,包括递归和迭代实现。递归方法基于分治思想,通过选取一个整数并与其他整数排列组合来求解;迭代方法则通过在已知排列基础上插入新整数于不同位置来生成新的排列。

问题描述

Given a collection of distinct integers, return all possible permutations.

给定一组不同的整数,返回所有可能的排列。

输入: [1,2,3]
输出:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

 

Python 实现

实现一:递归实现。根据排列的数学定义,求一组整数的排列,可以看做是依次选出一个整数后,分别与去掉该整数后剩下的这一组整数排列的结果进行组合。这也是分治法的思想,把大问题逐层向下分解成小问题,每一层小问题的结果组合起来就能解答目标问题。因此我们可以定义一个递归函数,用于求输入数组的排列,具体见以下代码:

class Solution(object):
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        
        ret = []
        
        def subPermute(nums, arr):
            if nums == None or len(nums) == 0:
                ret.append(arr)
                return
            
            for i in range(len(nums)):
                subPermute(nums[:i] + nums[i+1:], arr+[nums[i]])
        
        subPermute(nums, [])
        return ret

实现二:迭代实现。能用递归实现的算法基本都可以写成迭代的形式,这里为了更好的理解,思路上稍微做一点调整。同样是分解成求子数组的排列,假设我们已经求出了某个子数组的排列,给到下一个新的整数时,新的子问题就是在当前的排列结果得到新的排列结果,那我们可以把这个新整数依次插入在每个排列的结果的不同位置,这样就能得到到达该整数时,排列的结果。

class Solution(object):
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """

        if nums == None or len(nums) == 0:
            return [[]]
        
        ret = [[nums[0]]]
        
        idx = 1
        while idx < len(nums):
            tmp = []
            # Iterate each temperory permution result.
            for perm in ret:
                # Insert new number into each temperory permution result.
                for i in range(idx+1):
                    tmp.append(perm[:i] + [nums[idx]] + perm[i:])
            # Update the subpermution result and index.
            ret = tmp
            idx += 1
        return ret

 

链接:https://leetcode.com/problems/permutations/

### LeetCode 56 题目解析 LeetCode第56题要求解决区间合并的问题。给定一系列不重叠的区间,在这些区间中插入一个新的区间并进行合并,如果有必要的话[^1]。 ### 解决方案概述 为了有效地处理这个问题,可以先按照区间的起始位置对输入数组进行排序。接着遍历这个有序列表来判断当前区间是否与下一个区间有交集;如果有,则将这两个区间合并成一个更大的新区间继续比较下去直到完成整个过程[^2]。 ### C语言实现代码 下面是针对此问题的一个具体C语言解决方案: ```c #include <stdio.h> #include <stdlib.h> // 定义结构体表示区间 struct Interval { int start; int end; }; // 比较函数用于qsort()按start升序排列 int compare(const void* a, const void* b) { struct Interval *ia = (struct Interval *)a; struct Interval *ib = (struct Interval *)b; return ia->start - ib->start; } /** * Note: The returned array must be malloced, assume caller calls free(). */ struct Interval* merge(struct Interval* intervals, int intervalsSize, int* returnSize){ qsort(intervals, intervalsSize, sizeof(struct Interval), compare); // 动态分配内存存储结果 struct Interval *result = (struct Interval*)malloc(sizeof(struct Interval)*intervalsSize); *returnSize = 0; for (int i = 0; i < intervalsSize; ++i) { int L = intervals[i].start, R = intervals[i].end; if (!(*returnSize) || result[*returnSize-1].end < L) { result[(*returnSize)++] = intervals[i]; } else { result[*returnSize-1].end = fmax(result[*returnSize-1].end, R); } } return result; } ``` 该算法的时间复杂度主要取决于排序操作O(nlogn),其中n代表输入区间的数量。空间复杂度为O(1)(忽略返回的结果所占用的空间)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值