1.打印一个字符串中的所有子序列,如字符串String str = “abc”,那么它的子序列有" "、a、b、c、ab、ac、bc、abc。
解法:遍历字符串时,每一个字符都可以选择要或者不要。
def Subsequence(str):
# ans用来储存所有的结果
ans = []
path = ''
process(str, 0, ans, path)
return ans
def process(str, index, ans, path):
if index == len(str):
ans.append(path)
return
# 如果当前数组index位置,不保留
process(str, index+1, ans, path)
# 如果当前数组index位置,保留
process(str, index+1, ans, path + str[index])
Str = 'abc'
a = Subsequence(Str)
print(a)
2.汉诺塔问题。
在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:
(1) 每次只能移动一个盘子;
(2) 盘子只能从柱子顶端滑出移到下一根柱子;
(3) 盘子只能叠在比它大的盘子上。
请编写程序,用栈将所有盘子从第一根柱子移到最后一根柱子。
你需要原地修改栈。
解法:
假设n=1时,只有一个盘子,很简单,直接把它从A中拿出来,移动到C的位置上。
假设n=2时,我们就需要借助B,因为小盘子始终在大盘子上面,需要先把小盘子放到B中,再把A中的大盘子放到C中,最后把B中的小盘子放到C中。
如果有n个盘子呢,把n个盘子看成俩个部分,一部分有1个盘子,这是最底下的那个盘子,一部分有n-1个盘子,先将n-1个盘子移动到B,再将1个盘子从A移动到C中。最后将问题转化为如果将n-1个盘子移动到C中。依次类推,直至转化成1个盘子的问题时,问题就解决了。
class Solution(object):
def hanota(self, A, B, C):
"""
:type A: List[int]
:type B: List[int]
:type C: List[int]
:rtype: None Do not return anything, modify C in-place instead.
"""
n = len(A)
self.move(n, A, B, C)
def move(self, n, A, B, C):
# n=1时,直接把盘子从A移动到C
if n==1:
C.append(A[-1])
A.pop()
return
else:
# n>1时,先将上面n-1个盘子从A移动到B(子问题,递归)
# 再将最大的盘子从A移动到C
# 再将B上n-1个盘子从B移动到C(子问题,递归)
self.move(n-1, A, C, B)
C.append(A[-1])
A.pop()
self.move(n-1, B, A, C)
3.给定一个不含重复数字的数组 nums
,返回其 所有可能的全排列 。
解法:
class Solution(object):
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
def process1(first):
if first == n:
res.append(nums[:])
for i in range(first, n):
# 交换
nums[first], nums[i] = nums[i], nums[first]
process1(first + 1)
# 撤销
nums[first], nums[i] = nums[i], nums[first]
n = len(nums)
res = []
process1(0)
return res