zoukankan      html  css  js  c++  java
  • dfs 排列组合——找所有子集(重复元素和不重复元素)

    17. 子集

    中文
    English

    给定一个含不同整数的集合,返回其所有的子集。

    样例

    样例 1:

    输入:[0]
    输出:
    [
      [],
      [0]
    ]
    

    样例 2:

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

    挑战

    你可以同时用递归与非递归的方式解决么?

    注意事项

    子集中的元素排列必须是非降序的,解集必须不包含重复的子集。

    时间复杂度是O(2^n),本质就是在做二叉树的dfs。[1,2,3]举例:

                  root

                 /  

             不选中1  选中1

           /               /     

    不选中2  选中2  不选中2  选中2

     。。。。。

    使用dfs记录遍历路径即可。

    class Solution:
        """
        @param nums: A set of numbers
        @return: A list of lists
        """
        def subsets(self, nums):
            # write your code here
            path, results = [],[]
            self.helper(sorted(nums), 0, path, results)
            return results
        
        
        def helper(self, nums, index, path, results):
            if index == len(nums):
                results.append(list(path))
                return
            
            path.append(nums[index])
            self.helper(nums, index+1, path, results)
            
            path.pop()
            self.helper(nums, index+1, path, results)
    

    第二种写法是使用位运算,也比较直观,代码很容易写出来:

    class Solution:
        """
        @param nums: A set of numbers
        @return: A list of lists
        """
        def subsets(self, nums):
            # write your code here
            nums = sorted(nums)
            n = len(nums)
            results = []
            for i in range(1<<n):
                results.append(self.get_num(nums, i, n))
            return results
        
        
        def get_num(self, nums, num, cnt):
            result = []
            for i in range(cnt):
                if num & (1<<i):
                    result.append(nums[i])
            return result
    

    第三种写法是使用for dfs写法,看下面的图,以【1,2,3】为例:

                                                                        root (path=[])

                                                                           |

                                        ----------------------------------------

                                        |                                   |                                  |

                                        1                                   2                                 3

                                      /                                    |

                                    2      3                               3

                                   /

                                 3

    在遍历上述树的过程中将path全部记录下来(path不用走到叶子节点):

    class Solution:
        """
        @param nums: A set of numbers
        @return: A list of lists
        """
        def subsets(self, nums):
            # write your code here
            nums = sorted(nums)
            path, result = [], []
            self.dfs(nums, 0, path, result)
            return result
        
        
        def dfs(self, nums, index, path, result):
            result.append(list(path))
            
            if index == len(nums):
                return
            
            for i in range(index, len(nums)):
                path.append(nums[i])
                self.dfs(nums, i+1, path, result)
                path.pop()
    

    含有重复元素的子集问题,例如【1,2,2,3】

                                                    root (path=[])

                                                                           |

                                        ----------------------------------------

                                        |                                   |                  |                |

                                        1                                   2                2(重复)       3

                                      /                                  /                |

                                    2      3                           2     3            3

                                   /                                   |

                                 2    3                                3

                                 |

                                3

    又例如【1,1,2,3】

                                                    root (path=[])

                                                                           |

                                        ----------------|-------------------------

                                        |                           1(重复)         |                           |

                                        1                         /                   2                          3

                                      / |                     2    3                 |

                                    1    2   3                 |                       3

                                   /    |                      3        

                                 2   3  3                              

                                 |

                                3

    所以代码如下:

    class Solution:
        """
        @param nums: A set of numbers.
        @return: A list of lists. All valid subsets.
        """
        def subsetsWithDup(self, nums):
            # write your code here
            nums = sorted(nums)
            path, result = [], []
            self.dfs(nums, 0, path, result)
            return result
            
        
        def dfs(self, nums, index, path, result):
            result.append(list(path))
            
            for i in range(index, len(nums)):
                if i > 0 and nums[i] == nums[i-1] and i > index:
                    continue
                
                path.append(nums[i])
                self.dfs(nums, i+1, path, result)
                path.pop()
    
  • 相关阅读:
    WrapPanel虚拟化
    关于Windows执行cmd命令的坑之一
    C# .Net 获取当前电脑上的可移动磁盘
    关于WPF中资源字典的内存优化
    WPF获取ListBox、ListView之类列表的ScrollViewer实例
    C#事件与委托 yangan
    系统自动登录设置(适用所有操作系统) yangan
    Oracel小知识记录 yangan
    使用avaScript获取Url中的指定参数值 yangan
    Win7下破解ArcGIS 9.3方法 yangan
  • 原文地址:https://www.cnblogs.com/bonelee/p/11667428.html
Copyright © 2011-2022 走看看