zoukankan      html  css  js  c++  java
  • 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         3

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

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

    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]有重复元素存在就说明之前的路径已经走过。

    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"]
    
    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]
                
    
  • 相关阅读:
    从helloworld回顾程序的编译过程之二
    笔试题知识点记录
    jQuery面试题与答案
    hdu2586(How far away ?)
    解析PHP跳出循环的方法以及continue、break、exit的区别介绍
    如何查看任何一下网站的全部二级域名?
    urlencode()与urldecode()
    基于 LaravelAdmin 在十分钟内搭建起功能齐全的后台模板
    第一种方式:cookie的优化与购物车实例
    右键菜单的响应问题
  • 原文地址:https://www.cnblogs.com/bonelee/p/11668685.html
Copyright © 2011-2022 走看看