算法之回溯习题:排列组合问题

https:////www.cnblogs.com/liushoudong/articles/12396752.html

主要有三种类型的排列问题:

1.全排列

2.下一个排列

3.第k个排列

 

LeetCode31:下一个排列

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。

1,2,3 --> 1,3,2

3,2,1 --> 1,2,3

1,1,5 --> 1,5,1

解决方案:

方法一:暴力法

找出全排列,再排序

方法二:一遍扫描

 

LeetCode77:组合

给定两个整数n和k,返回1......n中所有可能的k个数的组合。

输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]

回溯法:是一种通过遍历所有可能成员来寻找全部可行解的算法。若候选不是可行解(或者至少不是最后一个解),回溯法会在前一步进行一些修改以舍弃该候选,换而言之,回溯并再次尝试。

 1 class Solution: # 根据排列组合
 2     def combine(self, n: int, k: int) -> List[List[int]]:
 3         nums = [i for i in range(1, n+1)]
 4         res = []
 5         ress = []
 6         self.combine_helper(nums, n, k, res, ress)
 7         return ress
 8     def combine_helper(self, nums, n, k, res, ress):
 9         if len(nums) == n-k:
10             ress.append(res)
11             return ress
12         for i in range(len(nums)):
13             x = res[:]
14             x.append(nums[i])
15             self.combine_helper(nums[i+1:], n-i, k, x, ress)
 1 #官方题解1:回溯法
 2 class Solution:
 3     def combine(self, n: int, k: int) -> List[List[int]]:
 4         def backtrack(first=1, cur=[]):
 5             if len(cur) == k:
 6                 res.append(cur[:])  
            return
7 for i in range(first, n + 1): 8 cur.append(i) 9 backtrack(i+1, cur) 10 cur.pop() 11 res = [] 12 backtrack() 13 return res

 字典序(二进制排序)组合:主要思路是以字典序的顺序获得全部组合。??

算法:将nums初始化为从1到k的整数序列。将n+1添加为末尾元素,起到“哨兵”的作用。

将指针设为列表的开头j=0

while j<k: 将nums中的前k个元素添加到输出中,换而言之,除了“哨兵”之外的全部元素

    找到nums中的第一个满足nums[j] + 1 != nums[j+1]的元素,并将其加一

    nums[j]++以转到下一个组合

 1 def combine(n, k):
 2     nums = list(range(1, k+1)) + [n+1]
 3     output, j = [], 0
 4     while j < k:
 5         output.append(nums[:k])
 6         j = 0
 7         while j < k and nums[j + 1] == nums[j] + 1:
 8             nums[j] = j + 1
 9             j += 1
10         nums[j] += 1
11     return output

LeetCode784:字母大小写全排列

给定一个字符串S,通过将字符串S中的每个字母转变大小写,我们可以获得一个新的字符串。返回所有可能得到的字符串集合。

示例:
输入: S = "a1b2"
输出: ["a1b2", "a1B2", "A1b2", "A1B2"]

输入: S = "3z4"
输出: ["3z4", "3Z4"]

输入: S = "12345"
输出: ["12345"]

 1 def letterCasePermutation(s):
 2     res = [[]]
 3     for x in s:
 4         n = len(res)
 5         if x.isalpha():
 6             for i in range(n):
 7                 res.append(res[i][:])
 8                 res[i].append(x.lower())
 9                 res[n + i].append(x.upper())
10         else:
11             for i in range(n):
12                 res[i].append(x)
13     return map(''.join, res)
14 S = 'a1b2'
15 print(list(letterCasePermutation(S)))

 

posted @ 2020-04-06 00:08  LinBupt  阅读(396)  评论(0)    收藏  举报