- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
首先,您有一个数组/列表 A,然后您想将其转换为给定的预期数组/列表 B。您可以对数组应用的唯一操作是 InsertAt
和 DeleteAt
,它们可以在列表中的特定索引处插入和删除元素。
note: Array B is always sorted while Array A may not be.
例如,您有一个数组 A 的 [1, 4, 3, 6, 7]
你希望它变成[2, 3, 4, 5, 6, 6, 7, 8]
一种方法是让 A 执行以下操作:
deleteAt(0); // which will delete element 1, arrayA now [4, 3, 6, 7]
deleteAt(0); // delete element 4 which now at index 0
// array A now [3, 6, 7]
insertAt(0, 2); // Insert value to at index 0 of array A
// array A now [2, 3, 6, 7]
insertAt(2, 4); // array now [2, 3, 4, 6, 7]
insertAt(3, 5); // array Now [2, 3, 4, 5, 6, 7]
insertAt(5, 6); // array Now [2, 3, 4, 5, 6, 6, 7]
insertAt(7, 8); // array Now [2, 3, 4, 5, 6, 6, 7, 8]
在上面的例子中,对数组 A 进行了 7 次操作,将其转换为我们想要的数组。
因此,我们如何找到将 A 转换为 B 的步骤,以及最少的步骤?谢谢!
顺便说一句,删除 A 处的所有元素然后将 B 中的所有元素添加到 A 的解决方案仅适用于 A 和 B 没有任何共同点的情况。
到目前为止我做了什么:
但是,我正在努力实现它......
7
的拼写错误,现在最少操作是 7。我的想法
部分最佳答案
我有一个 python 程序似乎可以工作,但它不是很短
__version__ = '0.2.0'
class Impossible(RuntimeError): pass
deleteAt = 'deleteAt'
insertAt = 'insertAt'
incOffset = 'incOffset'
def remove_all(size):
return [(deleteAt, i, None) for i in range(size-1, -1, -1)]
def index_not(seq, val):
for i, x in enumerate(seq):
if x != val:
return i
return len(seq)
def cnt_checked(func):
"""Helper function to check some function's contract"""
from functools import wraps
@wraps(func)
def wrapper(src, dst, maxsteps):
nsteps, steps = func(src, dst, maxsteps)
if nsteps > maxsteps:
raise RuntimeError(('cnt_checked() failed', maxsteps, nsteps))
return nsteps, steps
return wrapper
@cnt_checked
def strategy_1(src, dst, maxsteps):
# get dst's first value from src
val = dst[0]
try:
index = src.index(val)
except ValueError:
raise Impossible
# remove all items in src before val's first occurrence
left_steps = remove_all(index)
src = src[index:]
n = min(index_not(src, val), index_not(dst, val))
score = len(left_steps)
assert n > 0
left_steps.append([incOffset, n, None])
right_steps = [[incOffset, -n, None]]
nsteps, steps = rec_find_path(src[n:], dst[n:], maxsteps - score)
return (score + nsteps, (left_steps + steps + right_steps))
@cnt_checked
def strategy_2(src, dst, maxsteps):
# do not get dst's first value from src
val = dst[0]
left_steps = []
src = list(src)
for i in range(len(src)-1, -1, -1):
if src[i] == val:
left_steps.append((deleteAt, i, None))
del src[i]
n = index_not(dst, val)
right_steps = [(insertAt, 0, val) for i in range(n)]
dst = dst[n:]
score = len(left_steps) + len(right_steps)
nsteps, steps = rec_find_path(src, dst, maxsteps - score)
return (score + nsteps, (left_steps + steps + right_steps))
@cnt_checked
def rec_find_path(src, dst, maxsteps):
if maxsteps <= 0:
if (maxsteps == 0) and (src == dst):
return (0, [])
else:
raise Impossible
# if destination is empty, clear source
if not dst:
if len(src) > maxsteps:
raise Impossible
steps = remove_all(len(src))
return (len(steps), steps)
found = False
try:
nsteps_1, steps_1 = strategy_1(src, dst, maxsteps)
except Impossible:
pass
else:
found = True
maxsteps = nsteps_1 - 1
try:
nsteps_2, steps_2 = strategy_2(src, dst, maxsteps)
except Impossible:
if found:
return (nsteps_1, steps_1)
else:
raise
else:
return (nsteps_2, steps_2)
def find_path(A, B):
assert B == list(sorted(B))
maxsteps = len(A) + len(B)
nsteps, steps = rec_find_path(A, B, maxsteps)
result = []
offset = 0
for a, b, c in steps:
if a == incOffset:
offset += b
else:
result.append((a, b + offset, c))
return result
def check(start, target, ops):
"""Helper function to check correctness of solution"""
L = list(start)
for a, b, c in ops:
print(L)
if a == insertAt:
L.insert(b, c)
elif a == deleteAt:
del L[b]
else:
raise RuntimeError(('Unexpected op:', a))
print(L)
if L != target:
raise RuntimeError(('Result check failed, expected', target, 'got:', L))
start = [1, 4, 3, 6, 7]
target = [2, 3, 4, 5, 6, 6, 7, 8]
ops = find_path(start, target)
print(ops)
check(start, target, ops)
在用这段代码进行了一些测试之后,很明显结果是两个阶段的操作。有一个项目被删除的第一阶段初始列表,除了所有属于目标列表(重复)。然后将丢失的项目添加到列表中,直到目标列表已构建。
暂时的结论是,如果我们找到一个算法来确定最初出现在目标列表中的项目的最长子序列首先列出,以相同的顺序但不一定连续,然后给出最短路径。这是一个新的和可能更简单的问题。这可能就是您上面的意思,但从程序的输出中可以清楚得多。
很明显,这个问题可以归结为 longest increasing subsequence 的问题。
关于c - 将列表转换为所需数组的最小步骤算法。 (仅使用 InsertAt 和 DeleteAt),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41192639/
我正在尝试使用 jQuery 将 li 元素插入到 ul 元素的特定索引中。我似乎只能在列表末尾插入一个元素。我对 jQuery 很陌生,所以我可能没有正确思考。 最佳答案 尝试这样的事情: $("#
我有一个示例代码如下所示。 DataRow dr = DTSource.Rows[rowIndex]; //getting specified index row DTSource.Rows.Remo
情况 首先,您有一个数组/列表 A,然后您想将其转换为给定的预期数组/列表 B。您可以对数组应用的唯一操作是 InsertAt 和 DeleteAt,它们可以在列表中的特定索引处插入和删除元素。 no
我需要进行一些 FIFO 计算,因此我使用 singly-linked-list 当我尝试使用 insertAt(index,data) 方法在特定位置插入数据时,它不起作用。 var Linked
我以前从未使用过 Google Maps API,并且在网上找不到与此类似的问题。我在这里做一些非常基本的事情,我只想将 OpenSeaMaps 放在 Google map 之上。 我在网上看到了一些
我觉得我一定不能在这里做某事。我有一个 DataTable,它目前可以使用 DataTable.Rows.Add 方法获取我的参数,但是当我使用 DataTable.Rows.InsertAt 时它会
我是一名优秀的程序员,十分优秀!