此题解基于回溯算法。首先,初始化一个长度为2n-1的数组res,用于存放最终的序列。数组中的每个位置初始值为None,表示尚未放置任何数字。使用一个集合visited来记录当前已经被放置在序列中的数字。回溯函数recurse通过递归的方式尝试在序列res中放置数字,从n开始尝试到1,以确保字典序最大。对于每个数字i,如果i未被访问过,并且位置上的放置是可行的(对于大于1的i,需要确保res[idx + i]也未被占用),则将i放入当前位置和对应的间隔位置(如果i大于1)。然后,继续递归尝试填充下一个位置。如果递归成功,返回True;否则,撤销当前放置,尝试下一个数字。通过这种方式,算法尝试构建字典序最大的序列。
时间复杂度: O(n!)
空间复杂度: O(n)
class Solution:
def constructDistancedSequence(self, n: int) -> List[int]:
res = [None] * ((n << 1) - 1) # 初始化结果数组,长度为2n-1
visited = set() # 访问标记集合
self.recurse(res, n, 0, 1, visited)
return res
def recurse(self, res, n, idx, t, visited):
for i in range(n, 0, -1): # 从大到小尝试放置数字以保证字典序最大
if i in visited: # 如果数字已被使用则跳过
continue
if i > 1 and idx + i >= len(res): # 确保不会越界
continue
if i > 1 and res[idx + i] is not None: # 确保间隔位置未被占用
continue
visited.add(i) # 标记数字为已使用
res[idx] = i # 放置数字
if i > 1:
res[idx + i] = i # 放置间隔数字
if t == n: # 如果所有数字都已放置
return True
next_idx = idx + 1
while res[next_idx] is not None: # 寻找下一个空位置
next_idx += 1
if self.recurse(res, n, next_idx, t + 1, visited): # 递归放置下一个数字
return True
if i > 1:
res[idx + i] = None # 撤销间隔位置的放置
res[idx] = None # 撤销当前位置的放置
visited.remove(i) # 取消标记