TargetList和AvailableTagsList是两个字符串列表。 TargetList将包含Distinct字符串对象。
Input:
TargetList = {"cat", "dog"};
AvailableTagsList = {"cat", "test", "dog", "get", "spain", "south"};
Output: [0, 2] //'cat' in position 0; 'dog' in position 2
Input:
TargetList = {"east", "in", "south"};
AvailableTagsList = {"east", "test", "east", "in", "east", "get", "spain", "south"};
Output: [2, 7] //'east' in position 2; 'in' in position 3;
//'south' in position 6 (east in position 4 is not outputted as it is coming after 'in')
Input:
TargetList = {"east", "in", "south"};
AvailableTagsList = {"east", "test", "south"};
Output: [0] //'in' not present in availableTagsList
我将AvailableTags
中显示的字词位置存储到listMap
。
Map<String, List<Integer>> listMap = new HashMap<>();
int counter = 0;
for(String availableItem : AvailableTagsList)
{
if(listMap.containsKey(availableItem))
listMap.get(availableItem).add(counter);
else
{
List<Integer> temp = new ArrayList<>();
temp.add(counter);
listMap.put(availableItem, temp);
}
counter++;
}
我将listMap
中的所有元素列表添加到resultList
。
listMap will be like
"east" - [0,2,4]
"in" - [3]
"south" - [7]
resultList will have like [0,2,4,3,7]
我能用什么来解决这个问题,使用resultList
如何显示AvailableTagsList
中的最小子序列?我使用正确的方法吗?到目前为止我的进展情况如何?有没有其他替代方法来解决这个问题。
答案 0 :(得分:2)
我不知道该问题的最佳解决方案,但根据您的想法
public class MinimumCtsSubsequence {
static String[] words, tags;
public static void main(String[] args) {
words = new String[] { "east", "in", "south" };
tags = new String[] { "east", "test", "east", "in", "east", "get", "spain", "south" };
ArrayList<Integer> ans = minSubSequence();
for (int i = 0; i < ans.size(); ++i) {
System.out.print(ans.get(i) + " ");
}
}
static ArrayList<Integer> minSubSequence() {
ArrayList<Integer>[] occur = new ArrayList[words.length];
for (int i = 0; i < words.length; ++i)
occur[i] = new ArrayList<Integer>();
HashMap<String, Integer> indices = new HashMap<String, Integer>();
for (int i = 0; i < words.length; ++i) {
indices.put(words[i], i);
}
for (int i = 0; i < tags.length; ++i) {
String tag = tags[i];
if (indices.containsKey(tag)) {
int wordI = indices.get(tag);
occur[wordI].add(i);
}
}
// till now comp is o(n)
// loop throught all the starts that we have
int ans = Integer.MAX_VALUE;
int s1 = 0, e1 = 0;
for (int i = 0; i < occur[0].size(); ++i) {
int start = occur[0].get(i);
boolean poss = true;
int next = 0;
for (int j = 1; j < words.length; ++j) {
next = getNextGreater(start, occur[j]);
if (next == -1) {
poss = false;
break;
}
}
if (poss && ans > next - start) {
s1 = start;
e1 = next;
ans = next - start;
}
}
ArrayList<Integer> solu = new ArrayList<Integer>();
if (ans == Integer.MAX_VALUE) {
solu.add(0);
return solu;
}
solu.add(s1);
solu.add(e1);
return solu;
}
static int getNextGreater(int x, ArrayList<Integer> arr) {
int start = 0;
int end = arr.size() - 1;
int ans = -1;
while (start < end) {
int mid = (start + end) / 2;
if (arr.get(mid) <= x) {// go right
start = mid + 1;
} else {
ans = arr.get(mid);
end = mid;
}
}
if (start == end && arr.get(start) > x)
return arr.get(start);
return ans;
}
答案 1 :(得分:0)
我倾向于将事物视为图形问题,因此我将其视为图形问题*。在完成您已经完成的列表映射步骤之后,您可以构建一个图形,最终找到最短路径。
因为你想要开始和结束的位置,你需要跟踪哪些节点形成最短的路径,以及它们来自哪个位置,以便你可以返回这些节点&#39;位置。这是一种非常典型的最短路径算法扩充,可能的例子和指导可以在互联网上找到。
*我不主张这必然是一个不错的选择,或者是最快或最简单的选择,但它会起作用。
**这里有一个优化,你可以让每个w1节点都有一个到下一个w1节点的边缘,每个w1节点只连接到位置大于它的最近的w2节点。 / p>
有几个小时的时间来考虑这个,我很确定你可以在O(n)时间和空间中这样做(使用优化的图形,并从输入中仔细构建它)。所以它至少不会非常缓慢。
答案 2 :(得分:0)
一种方法是不合并初始问题中提供的那些列表。
您必须意识到范围只会受到第一个和最后一个标记的索引的影响。中间发生的事情不会真正影响范围(如果确实存在)。
话虽如此,对于任何有效的解决方案都需要有两个约束条件。
如果每个标签都有一个索引列表,那么如果从左侧按顺序从每个标签移动:
如果你从右边移动:
基本上,你试图从两端缩小。
如果您无法满足这些约束条件,那么您就知道没有有效的解决方案。
我不知道这是否是最佳解决方案或方法。但它会起作用。