美文网首页算法学习
算法题--全排列

算法题--全排列

作者: 岁月如歌2020 | 来源:发表于2020-04-02 11:18 被阅读0次
image.png

0. 链接

题目链接

1. 题目

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

Example:

Input: [1,2,3]
Output:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

2. 思路1:中介数法

例如1,2,3全排列按顺序列出,一共有3!=3*2*1=6种方式,如下:

1,2,3
1,3,2
2,1,3
2,3,1
3,1,2
3,2,1

获得当前排列的下一个排列的过程如下, 以1,2,3为例:

  • 从右往左找到第一个变小的数字2
  • 从右往左找到第一个比2大的数字3
  • 交换2和3, 得到1,3,2
  • 将3之后的数字按位置倒序排列(注意不是按值), 得到1,3,2

同理, 1,3,4,2的下一个排列的过程如下:

  • 从右往左找到第一个变小的数字3
  • 从右往左找到第一个比3大的数字4
  • 交换34, 得到1,4,3,2
  • 4之后的数字按位置倒序排列, 得到1,4,2,3

另外,对于初始排列不是从小到大的情况,为了得到全排列,可以对数组下标执行上述的找下一个排列的步骤,直到最后一个排列完全倒序,无法再找到下一个排列,则得到了全排列。

例如

[0,-1,1]

并非一个纯升序排列
但可以取下标

[0,1,2]

依次得到

[0,1,2] --> [0,-1,1]
[0,2,1] --> [0,1,-1]
[1,0,2] --> [-1,0,1]
[1,2,0] --> [-1,1,0]
[2,0,1] --> [1,0,-1]
[2,1,0] --> [1,-1,0]

最终得到汇总结果

[
    [0, -1, 1], 
    [0, 1, -1], 
    [-1, 0, 1], 
    [-1, 1, 0], 
    [1, 0, -1], 
    [1, -1, 0]
]

3. 代码

# coding:utf8
from typing import List

class Solution:
    def next_permutation(self, nums: List[int]) -> bool:
        left_idx = None
        size = len(nums)

        i = size - 1
        while i > 0:
            if nums[i] > nums[i - 1]:
                left_idx = i - 1
                break
            i -= 1

        if left_idx is None:
            return False

        i = size - 1
        while i > left_idx:
            if nums[i] > nums[left_idx]:
                nums[i], nums[left_idx] = nums[left_idx], nums[i]
                break
            i -= 1

        l = left_idx + 1
        r = size - 1
        while l < r:
            nums[l], nums[r] = nums[r], nums[l]
            l += 1
            r -= 1

        return True

    def permute(self, nums: List[int]) -> List[List[int]]:
        rtn_list = list()
        if len(nums) <= 1:
            rtn_list.append(nums.copy())
            return rtn_list
        else:
            nums_index_list = list(range(len(nums)))
            rtn_list.append(list(map(lambda idx: nums[idx], nums_index_list)))

            while 1:
                if self.next_permutation(nums_index_list):
                    rtn_list.append(list(map(lambda idx: nums[idx], nums_index_list)))
                else:
                    break

        return rtn_list


solution = Solution()
print(solution.permute([1, 2, 3]))
print(solution.permute([1, 2, 3, 4]))
print(solution.permute([0, -1, 1]))

输出结果

[
    [1, 2, 3], [1, 3, 2], 
    [2, 1, 3], [2, 3, 1], 
    [3, 1, 2], [3, 2, 1]
]

[
    [1, 2, 3, 4], [1, 2, 4, 3], [1, 3, 2, 4], [1, 3, 4, 2], [1, 4, 2, 3], [1, 4, 3, 2], 
    [2, 1, 3, 4], [2, 1, 4, 3], [2, 3, 1, 4], [2, 3, 4, 1], [2, 4, 1, 3], [2, 4, 3, 1], 
    [3, 1, 2, 4], [3, 1, 4, 2], [3, 2, 1, 4], [3, 2, 4, 1], [3, 4, 1, 2], [3, 4, 2, 1], 
    [4, 1, 2, 3], [4, 1, 3, 2], [4, 2, 1, 3], [4, 2, 3, 1], [4, 3, 1, 2], [4, 3, 2, 1]
]

[
    [0, -1, 1], [0, 1, -1], 
    [-1, 0, 1], [-1, 1, 0], 
    [1, 0, -1], [1, -1, 0]
]

4. 结果

image.png

相关文章

  • 算法题--全排列

    0. 链接 题目链接 1. 题目 Given a collection of distinct integers,...

  • 算法题--全排列II

    0. 链接 题目链接 1. 题目 Given a collection of numbers that might...

  • 46. Permutations

    算法 1: 递归数组 的全排列,等价于全排列与可能的取值组合得到。 算法 2: 计算一个排列 按字典升序排列的紧...

  • leetcode力扣 46 全排列

    借着这个题,复习一下全排列:以下介绍全排列算法四种: (A)字典序法 (B)递增进位制数法 (C)递减进位制数法 ...

  • 全排列与字典序

    全排列 递归实现全排列; 首先来说递归算法实现全排列: 例如,对于{1,2,3,4}的例子进行全排列,其可以分解...

  • 46、全排列 | 算法(leetcode,附思维导图 + 全部解

    零 标题:算法(leetcode,附思维导图 + 全部解法)300题之(46)全排列 一 题目描述 二 解法总览(...

  • 全排列算法

    参考资料 先上代码,实现非常简洁 输出 主要思路 在此树中,每一个从树根到叶子节点的路径,就对应了集合A的一个排列...

  • 全排列算法

    4个数的全排列 结果 任务分配问题

  • 全排列算法

    问题: 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,...

  • 全排列算法

    题目:给定元素a,b,a,b,c,c,d,求解出所有的排列。思路:首先这道题的算法是一个比较经典的算法,它并不是使...

网友评论

    本文标题:算法题--全排列

    本文链接:https://www.haomeiwen.com/subject/ufatphtx.html