赞
踩
最近连着两周打比赛都遇到了字符串字典序的相关问题,然后还连着两周都在这个坑里面摔死,简直了……
因此,就趁着这个假期来整理一下字典序相关的内容,省的后面再在同一个问题上摔倒了……
我们首先来看一下字典序排序的定义。
考察两个字符串s
以及s'
,s
字典序在s'
之前的判断条件为:
def is_smaller(s1, s2):
n, m = len(s1), len(s2)
i = 0
while i < n and i < m:
if s1[i] == s2[i]:
i += 1
elif s1[i] < s2[i]:
return True
else:
return False
return i == n and i < m
可以看到:
现在,我们来看如何来获取字典序排列的邻接字符串,即按照字典序排序的次大或者次小字符串。
我们首先以字典序排序的次小字符串的次小字符串为例进行考察。
显而易见的,它必然要求我们将字符串中的某一个元素替换为后续字符串中某一个比它更小的字符,而这个字符必须是后方字符中最靠近该字符的一个,然后,我们需要需要对后方字符进行调整,使得其按照顺序排列,确保它是最大的那个子串。
leetcode的1830题当中给出了一种制式化但是简单直接的获取过程,即:
换用代码语言即:
def get_next(s):
n = len(s)
i = n-1
while i > 0 and s[i] >= s[i-1]:
i -= 1
j = i
while j < n and s[j] < s[i-1]:
j += 1
j -= 1
s = s[:i-1] + s[j] + (s[i:j] + s[i-1] + s[j+1:])[::-1]
return s
而关于上述方法为什么在逻辑上是可行的,这个事实上也是比较显然的。
根据步骤1,显然从下标i开始的后续子串是递增的,而根据步骤2,s[j]是子串s[i:]
之后当中小于s[i-1]的最大字符,交换s[i-1]与s[j]之后,显然字符串在字典序上变小了,且s[i:]
依然保持有序,此时再将s[i:]
进行倒序操作,就能够获取前缀为s[:i]
时的子串的最大字典序子串,即之前一个子串的次小字典序子串。
我们仿照上述获取次小字符串的方法,同样可以给出制式化的获取次大字符串的步骤如下:
同样可以给出代码实现如下:
def get_next(s):
n = len(s)
i = n-1
while i > 0 and s[i] <= s[i-1]:
i -= 1
j = i
while j < n and s[j] > s[i-1]:
j += 1
j -= 1
s = s[:i-1] + s[j] + (s[i:j] + s[i-1] + s[j+1:])[::-1]
return s
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。