问题1: 给定字符串1234无重复字符,求其所有排列
递归方式求解:
def swap(num, i, j):
tmp = num[i]
num[i] = num[j]
num[j] = tmp
#num无重复数字
def fullSort(num, index):
if index==len(num)-1:
print (num)
return
for i in range(index, len(num)):
swap(num, index, i)
fullSort(num, index+1)
swap(num, index, i)
以1234为例,首先考虑第一位的可能,有1,2,3,4四种可能,当第一位固定时,例如为1,后面三位又是一个递归问题,用变量index来标识当递归到数组的第几位
当index==len(num)-1时,说明所有数字已经交换完毕,则输出数组即可,此时为一种排列。
当index<len(num)-1时,说明例如index=0,说明当前正在考虑第index位的取值,可以把index+1一直到len(num)-1所有数字都置换到num[index]中,然后依次求解每个递归问题
在每一次递归循环中,数组的位置索引信息 0----index----i------len-1
index表示数组的位置索引,index取值0----len-1
当index确定某一值时,该位置的取值方式可以为i=index--len-1,依次将后面数字i交换到该位置index,递归求解子问题
当index==len-1,说明所有可能交换情况已经完成,可以输出该数组,即为一种排列方式
问题2:给定字符串12234,求其所有排列字符串要去重
数组索引:
0---index---i----len-1
考虑将num[index]与num[i]交换,若在index--i-1中已经存在num[i],则num[i]不应该与num[index]交换,因为交换依次为按顺序交换,i取值从index一直到i,若这中间出现过num[i],说明num[index]已经被交换过,若再次交换便会出现重复。
例如 num = [1 2 2 3 4] :
index=1 i的变化范围从1---4,当i=2时,此时num[i]=2,而在index=0---i-1=1之间num[1]=2,说明num[1]已经出现在num[0]位置上,若num[2]再次与num[0]交换,则会出现重复排列。
因此在每次将num[i]与num[index]交换时,需要考虑 num[i]在num[index:i]中是否出现过:
def isSwap(num, index, i):
for j in range(index, i):
if num[j]==num[i]:
return False
return True
去重的排列方式如下:
#num中有重复数字
def fullSort2(num, index):
if index==len(num)-1:
print (num)
return
for i in range(index, len(num)):
#print (isSwap(num, index, i))
if isSwap(num, index, i):
swap(num, index, i)
fullSort2(num, index+1)
swap(num, index, i)
问题3:给定字符串1234,求其所有排列,使用非递归方式
非递归解法:
给定一个数字字符串,将其看成一个整数,若每次都寻找一个比它刚好更大的数输出,继续寻找比上一个更大的数字,这样依次输出,则可以输出所有组合,并且不会重复。
寻找一个比某数刚好更大的方法:
给定数字字符串数组,从后往前寻找,寻找一个相邻递增的两个数,则前一个数称为替换数,其索引称为替换点;然后从替换点之后开始寻找一个比替换数大的最小数,称为被替换数;交换替换数以及被替换数;将替换点之后的所有数字翻转;输出该数字即时目标值。
例如: num=[5,4,7,8,2,0] 从后往前寻找相邻递增的两个数为7,8,则替换数为7 替换点为index=2 从替换点往后寻找比替换数大的最小值,即被替换数为8,交换7,8 得548720,把替换点之后的数字给翻转 得到548027 。即比547820大的第一个数为548027
输出一个数组,首先进行排序获取到最小值,然后依次执行上述过程,逐次增大该数,一直到最大值结束即可。
#寻找比替换点大的最小数,倒序寻找,第一个大的数就是目标值
def findBiggerThanReplaceNum(num, r):
min = r
for i in range(len(num)-1, r, -1):
if num[i]>num[r]:
return i
return min
def reverse(num, i, j):
while i<j:
swap(num, i, j)
i += 1
j -= 1
def fullSort3(num):
num.sort()
print (num)
#替换数的下标 排序完成后第一个数
r = len(num)-1
#替换点的下一个数坐标
m = r
while r>0:
m = r
r -= 1
#print ('r = ', r)
if num[r]<num[m]:
s = findBiggerThanReplaceNum(num, r)
#print ('s = ',s)
swap(num, r, s)
reverse(num, r+1, len(num)-1)
print (num)
#break
r = len(num)-1
首先排序数组
r表示循环寻找替换点变量 m表示为r下一个索引
若num[r]<num[m]则说明r为替换点,找到替换点之后比替换数大的最小值被替换数s,从后往前第一个比替换数大的数即为被替换数
交换替换数以及被替换数
翻转替换数之后的所有字符
r指向数组末尾len-1,继续循环
当数组已经完全降序输出时,r从len-1一直到0,当r=0,m=1此时num[r]<num[m]仍不满足,则退出循环,结束遍历。