dfs 全排列 使用交换——含重复元素和非重复元素

15. 全排列

中文
English

给定一个数字列表,返回其所有可能的排列。

样例

样例 1:

输入:[1]
输出:
[
  [1]
]

样例 2:

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

挑战

使用递归和非递归分别解决。

注意事项

你可以假设没有重复数字。

(A、B、C、D)的全排列为

1、A后面跟(B、C、D)的全排列

2、B后面跟(A、C、D)的全排列(A与B交换,其他次序保持不变)

3、C后面跟(B、A、D)的全排列(A与C交换,其他次序保持不变)

4、D后面跟(B、C、A)的全排列(A与D交换,其他次序保持不变)

 

举例说明,【1,2,3】:

                  root

              /      |    \

           1        2       3

        /  \       / \      / \

       2    3    1    3    1   2

      /       \   ...         ....

    3         2

也就是说:permutate([1,2,3]) = {[1]+permutate([2,3]),  [2]+permutate([1,3]), [3]+permutate([1,2])}

使用交换思路后编码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution:
    """
    @param: :  A list of integers
    @return: A list of unique permutations
    """
 
    def permute(self, nums):
        # write your code here
        result = []
        self.find_permutations(nums, 0, result)
        return result
 
 
    def find_permutations(self, nums, start_index, result):
        if start_index >= len(nums):
            result.append(list(nums))
            return
 
        for i in range(start_index, len(nums)):
            nums[start_index], nums[i] = nums[i], nums[start_index]
            self.find_permutations(nums, start_index + 1, result)
            nums[start_index], nums[i] = nums[i], nums[start_index]

 

 

含有重复元素的全排列:

举例说明,【1,1,2】:

                    root

              /        |          \

           1         1(重复)       2

        /  \       / \             / \

       1    2     2    1          1    1(重复)

      /       \    |     |          |     |

    2         1    1    2         1    1

 

 

再举例说明,【1,2,2】:

 

                           root

 

              /               |          \

 

           1                 2              2(重复)

 

        /  \               / \             / \

 

       2    2(重复)2    1         1     2   

 

      /       \           |     |          |     |

 

    2         2          1    2         2    1

 


 

代码如下:就是用比较无脑的交换做法,当前交换的元素nums[i], 只要在nums[start_index:i]有重复元素存在就说明之前的路径已经走过。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution:
    """
    @param: :  A list of integers
    @return: A list of unique permutations
    """
 
    def permuteUnique(self, nums):
        # write your code here
        result = []
        self.find_permutations(nums, 0, result)
        return result
 
    def find_permutations(self, nums, start_index, result):
        if start_index >= len(nums):
            result.append(list(nums))
            return
 
        for i in range(start_index, len(nums)):
            if nums[i] in nums[start_index:i]:
                continue
             
            nums[start_index], nums[i] = nums[i], nums[start_index]
            self.find_permutations(nums, start_index + 1, result)
            nums[start_index], nums[i] = nums[i], nums[start_index]

 

 和不重复元素的全排列算法比较看来,无非就是多了一个swap的判断。

 

10. 字符串的不同排列

中文
English

给出一个字符串,找到它的所有排列,注意同一个字符串不要打印两次。

样例

样例 1:

输入:"abb"
输出:
["abb", "bab", "bba"]

样例 2:

输入:"aabb"
输出:
["aabb", "abab", "baba", "bbaa", "abba", "baab"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution:
    """
    @param str: A string
    @return: all permutations
    """
    def stringPermutation2(self, str):
        # write your code here
        self.result = []
        self.dfs(s=list(str), start_index=0)
        return ["".join(w) for w in self.result]
         
     
    def dfs(self, s, start_index):
        if start_index == len(s):
            self.result.append(s[:])
            return
         
        for i in range(start_index, len(s)):
            if s[i] in s[start_index:i]:
                continue
             
            s[start_index], s[i] = s[i], s[start_index]
            self.dfs(s, start_index+1)
            s[start_index], s[i] = s[i], s[start_index]
            

 

 

posted @   bonelee  阅读(604)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示