TargetList and AvailableTagsList are two lists of string. TargetList will contain Distinct string objects.
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
I store the positions of words where they appear in the AvailableTags into a 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++;
}
And I add all element list in listMap to a resultList.
listMap will be like
"east" - [0,2,4]
"in" - [3]
"south" - [7]
resultList will have like [0,2,4,3,7]
What I can't wrap my head around with is, using this resultList how do I display the minimum subsequence in the AvailableTagsList? Am I using the right approach? How is my progress so far? Are there any other alternative approaches to solve this problem.
I don't know the optimum solution for this problem but according to your idea
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With