Java 产生给定后缀数组的最小不同字符数
给定一个后缀数组,SRM 630的TopCoder任务要求查找字符串中可形成具有给定后缀数组的字符串的最小不同字符数。这个 我找到的最佳解决方案就在这里: 以下是ftiasch编写的算法:Java 产生给定后缀数组的最小不同字符数,java,algorithm,dynamic-programming,suffix-array,Java,Algorithm,Dynamic Programming,Suffix Array,给定一个后缀数组,SRM 630的TopCoder任务要求查找字符串中可形成具有给定后缀数组的字符串的最小不同字符数。这个 我找到的最佳解决方案就在这里: 以下是ftiasch编写的算法: public int minimalCharacters(int[] array) { int n = array.length; int[] position = new int[n + 1]; for (int i = 0; i < n; ++i) { pos
public int minimalCharacters(int[] array) {
int n = array.length;
int[] position = new int[n + 1];
for (int i = 0; i < n; ++i) {
position[array[i]] = i;
}
position[n] = -1;
int[] minimum = new int[n + 1];
for (int i = n - 1; i >= 0; --i) {
minimum[i] = Integer.MAX_VALUE;
for (int j = i + 1; j <= n; ++j) {
boolean valid = true;
for (int x = i; x < j; ++x) {
for (int y = x + 1; y < j; ++y) {
valid &= position[array[x] + 1] < position[array[y] + 1];
}
}
if (valid && minimum[j] < Integer.MAX_VALUE) {
minimum[i] = Math.min(minimum[i], minimum[j] + 1);
}
}
}
return minimum[0];
}
public int最小字符数(int[]数组){
int n=数组长度;
int[]位置=新int[n+1];
对于(int i=0;i=0;--i){
最小值[i]=整数最大值;
对于(int j=i+1;j这里有一个二次时间算法。后缀数组为每个算法指定
一对后缀,它们是如何按字典顺序进行比较的(和空后缀)
后缀总是小于所有后缀)。让s
成为未知字符串
假设我们将后缀s[i..]
与后缀s[j..]
进行比较。
如果s[i]!=s[j]
,那么s[i]
和s[j]
的比较就解决了这个问题。
否则,结果与比较s[i+1…]
和
s[j+1…]
假设我们希望确保s[i..]
,显然我们需要
s[i]位置[j]:
如果位置[i+1]>位置[j+1]否则为1,则w=0
图[i].追加((w,j))
备注={None:-1}
对于范围(n)中的i:
长度路径(图表、备忘录、i)
返回最大值(memo.values())+1
def minChars3(阵列):
n=len(数组)
位置=[无]*n
对于范围(n)中的i:
位置[array[i]]=i
对于范围(n)内的k:
对于itertools.product中的s(范围(k),重复=n):
有效=真
对于范围(n)中的i:
对于范围(n)内的j:
valid=valid和(s[i:如果位置[array1[i]+1]需要一个更好的问题标题。你喜欢“需要有人一步一步地解释这个代码是如何工作的”@Takendarkk这似乎更像是一个概念性的问题:为什么这个算法解决了眼前的问题?对我来说,它背后的想法并不明显,尽管我完全理解每一行的作用individually@NiklasB.这正是我的想法。即使我理解每一行代码,我也不理解该算法如何解决这个问题。我知道如何计算具有最大权重的路径,但构建图形的方式不太清楚。请您用编程语言重写此LOC,最好是java?graph={I:[(int(位置[I+1]>位置[j+1]),j)表示范围(n)中的j,如果位置[I]
@Ariel I将理解替换为循环,在测试新代码时,发现两个以前的版本都不正确。我添加了一个蛮力版本进行比较。@Ariel I添加了线性时间解决方案的说明和代码。您的算法中是否使用基于一的索引数组?@Ariel原来我是在解释输入作为逆排列。现在所有的东西都是固定的,所有四个版本都同意所有的小输入。
public int minimalCharacters(int[] array) {
int n = array.length, i;
if (n == 0)
return 0;
int[] array1 = new int[n + 1];
for (i = 0; i < n; i++)
array1[1 + i] = array[i];
int[] position = new int[n + 1];
for (i = 0; i < n + 1; i++)
position[array1[i]] = i;
int k = 1;
for (i = n; i > 1; i--) {
if (position[array1[i] + 1] <= position[array1[i - 1] + 1])
k++;
}
return k;
}
def minChars1(array):
n = len(array)
position = [-1] * (n + 1)
for i in range(n):
position[array[i]] = i
infinity = n + 1
minimum = [infinity] * (n + 1)
minimum[n] = 0
for i in range(n - 1, -1, -1):
for j in range(i + 1, n + 1):
valid = True
for x in range(i, j):
for y in range(x + 1, j):
valid = valid and position[array[x] + 1] < position[array[y] + 1]
if valid and minimum[j] < infinity:
minimum[i] = min(minimum[i], minimum[j] + 1)
return minimum[0]
def lengthOfLongestPath(graph, memo, i):
if i not in memo:
result = 0
for w, j in graph[i]:
result = max(result, w + lengthOfLongestPath(graph, memo, j))
memo[i] = result
return memo[i]
def minChars2(array):
n = len(array)
position = [-1] * (n + 1)
for i in range(n):
position[array[i]] = i
graph = {}
for i in range(n):
graph[i] = []
for j in range(n):
if position[i] > position[j]:
w = 0 if position[i + 1] > position[j + 1] else 1
graph[i].append((w, j))
memo = {None: -1}
for i in range(n):
lengthOfLongestPath(graph, memo, i)
return max(memo.values()) + 1
def minChars3(array):
n = len(array)
position = [None] * n
for i in range(n):
position[array[i]] = i
for k in range(n):
for s in itertools.product(range(k), repeat=n):
valid = True
for i in range(n):
for j in range(n):
valid = valid and (s[i:] < s[j:]) == (position[i] < position[j])
if valid:
return k
return n
def minChars4(array):
n = len(array)
if n == 0:
return 0
array1 = [n] * (n + 1)
for i in range(n):
array1[1 + i] = array[i]
position = [None] * (n + 1)
for i in range(n + 1):
position[array1[i]] = i
k = 1
for i in range(n, 1, -1):
if position[array1[i] + 1] <= position[array1[i - 1] + 1]:
k += 1
return k
def test():
for n in range(7):
for array in itertools.permutations(range(n)):
assert minChars1(array) == minChars2(array) == minChars3(array) == minChars4(array)
test()