1、错误示范
看到题目中从arr中找到target最长的子串,想都不想直接递归
class Solution(object):
def minOperations(self, target, arr):
"""
:type target: List[int]
:type arr: List[int]
:rtype: int
"""
# 去重,减少运算量
for x in arr[:]:
if x not in target:
arr.remove(x)
num = 0
for index in range(len(target)):
if target[index] not in arr:
num += 1
else:
if index + 1 == len(target):
pass
else:
list_more = []
size_a = len(arr)
index_list_a = [i for i, x in enumerate(arr) if x == target[index]]
for a_x in index_list_a:
if a_x + 1 == size_a:
num_yes = len(target) - index - 1
else:
num_yes = self.minOperations(target[index + 1:], arr[a_x + 1:])
# num_yes = self.realFunction(target[index+1:], arr[a_x+1:])
num_no = self.minOperations(target[index + 1:], arr) + 1
num_temp = num_yes if num_yes < num_no else num_no
list_more.append(num_temp)
num += min(list_more)
break
return num
结果可想而知,超时超时超时!
为了减少重复计算,考虑加入记忆列表保存部分结果,但是结果依然不理想,思来想去,放弃递归。
2、正确示范
由target的数据互不相同,因此本题中寻求最长公共子序列就变成了寻求最长递增公共子序列。
将target的值与坐标做一个映射,同时arr也根据target的索引与值做同样的变化。
比如示例1:
target_index = {5:0, 1:1, 3:2}
arr_index = {-1, -1, -1, 2, -1}
arr中不在target的元素对结果没影响,这里用-1表示(实际上完全没必要)
e_list用于存储目标序列
class Solution(object):
def minOperations(self, target, arr):
"""
:type target: List[int]
:type arr: List[int]
:rtype: int
"""
target_index = {e: index for index, e in enumerate(target)}
e_list = []
for arr_e in arr:
if arr_e in target_index:
index = target_index[arr_e]
n_index = bisect.bisect_left(e_list, index)
if len(e_list) > n_index:
e_list[n_index] = index
else:
e_list.append(index)
return len(target) - len(e_list)
这里有一个很容易坑人的地方,注意看这个个代码,与上面的差异:
class Solution(object):
def minOperations(self, target, arr):
"""
:type target: List[int]
:type arr: List[int]
:rtype: int
"""
target_index = {e: index for index, e in enumerate(target)}
e_list = []
for arr_e in arr:
if arr_e in target:
index = target_index[arr_e]
n_index = bisect.bisect_left(e_list, index)
if len(e_list) > n_index:
e_list[n_index] = index
else:
e_list.append(index)
num = len(target) - len(e_list)
return num
差别就在:
if arr_e in target_index
if arr_e in target
在python中 if x in list 与 if x in dict效率差别很大,因此上面可以轻松通过,下边会导致超时,因此能用dict就不用list判断存在