forked from sinagarajan/Algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSubSegmentOfString.java
More file actions
211 lines (158 loc) · 5.62 KB
/
Copy pathSubSegmentOfString.java
File metadata and controls
211 lines (158 loc) · 5.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/*
Given a paragraph of text, write a program to find the first shortest sub-segment that contains each of the given k words at least once. A segment is said to be shorter than other if it contains less number of words.
Ignore characters other than [a-z][A-Z] in the text. Comparison between the strings should be case-insensitive.
If no sub-segment is found then the program should output “NO SUBSEGMENT FOUND”.
Input format :
First line of the input contains the text.
Next line contains k , the number of words given to be searched.
Each of the next k lines contains a word.
Output format :
Print first shortest sub-segment that contains given k words , ignore special characters, numbers.If no sub-segment is found it should return “NO SUBSEGMENT FOUND”
Sample Input :
This is a test. This is a programming test. This is a programming test in any language.
4
this
a
test
programming
Sample Output :
a programming test This
Explanation :
In this test case segment "a programming test. This" contains given four words. You have to print without special characters, numbers so output is "a programming test This". Another segment "This is a programming test." also contains given four words but have more number of words.
Constraint :
Total number of character in a paragraph will not be more than 200,000.
0 < k <= no. of words in paragraph.
0 < Each word length < 15
Algorithm :
1. Replace all the special characters in the string and remove the duplicates in the input string
2. HashMap (getIndex) stores the input value
this 0
a 1
test 2
programming 3
3. Get the input string one by one and store occuring index in another HashMap as well as ArrayList
ArrayList[0] (occurence of 'this') 0 4 9
ArrayList[1] (occurence of 'a') 2 6 11
ArrayList[2] (occurence of 'test') 3 8 13
ArrayList[3] (occurence of 'prog') 7 12
4. Second Hashmap (mapIndex) contains mapping between occurence and index hashmap 0-0 2-1 3-2 4-0 6-1 7-3 8-2 9-0 11-1 12-3 13-2
5. For each element in the hashmap, find the neighbor occurrences
Example: (6) nearest occurrence of 'this' 4 , 'test' 8 , 'prog' 7 . Hence , minimum = 4, maximim = 8 .Length =5
Repeat for each and find the lowest length.
(NOTE: Second HashMap is included here so that we can find the occurrence sorted manner )
*/
import java.util.*;
public class Solution {
public static int k;
public static String input_string[];
public static HashMap<String,Integer> getIndex;
public static ArrayList<Integer>[] arrays;
public static Map<Integer,Integer> mapIndex;
public static int min = 200000;
public static int max = 0;
public static int length = 200000;
/* Prints the output in required format */
public static void print()
{
for(int i=min; i<max; i++)
{
System.out.print(input_string[i] + " ");
}
System.out.print(input_string[max]);
}
/* Gets the closest occurrence of the given word in each occurrences */
public static int getNearby(int data, int level)
{
int tempLength=200000,tempMin=200000,temp;
for(int i=0; i< arrays[level].size();i++)
{
temp=Math.abs(data - arrays[level].get(i));
if ( temp < tempLength)
{
tempLength = temp;
tempMin = arrays[level].get(i);
}
}
return tempMin;
}
/* Calculate Minimum occurrence and Maximum occurrence of each word */
public static void findanswer(int data, int level)
{
int currMin=data,currMax=data;
for(int i=0;i< arrays.length; i++)
{
if(i==level) continue;
int temp = getNearby(data , i);
currMin = Math.min(currMin,temp);
currMax = Math.max(currMax,temp);
//Update only during final iteration
if(i==(arrays.length - 1))
{
if(length > (currMax-currMin +1))
{
length = currMax-currMin +1;
min = currMin;
max = currMax;
}
}
}
}
public static void main(String[] args)
{
int j=0;
Scanner in = new Scanner(System.in);
String str = in.nextLine();
//Replace all speacial characters
str = str.replaceAll("[,|.|!|@|#|$|%|^|&|*|(|)|{|}|<|>|/|-|_|~|`|\\d]", "");
str = str.replaceAll("( )+", " ");
k = in.nextInt();
//One hash maps stores the index of each input string and the other stores level of each occurrence
getIndex = new HashMap<String,Integer>();
mapIndex = new HashMap<Integer,Integer>();
in.nextLine();
input_string = str.split(" ");
//Input the string from the user
for(int i=0; i < k; i++)
{
String s = in.nextLine().toLowerCase();
if(getIndex.get(s)== null)
{
getIndex.put(s, j);
j++;
}
}
arrays= new ArrayList[j];
for(int itr=0; itr< j; itr++)
arrays[itr]= new ArrayList<Integer>();
int temp;
for(int i=0; i<input_string.length; i++)
{
try
{
temp =getIndex.get(input_string[i].toLowerCase());
}
catch(Exception e)
{
continue;
}
arrays[temp].add(i);
mapIndex.put(i,temp);
}
//No need to wait for multiple characters
for(int i=0; i<arrays.length; i++)
{
if(arrays[i].size()==0)
{
System.out.println("NO SUBSEGMENT FOUND");
return;
}
}
//Calls the answer for each occurrence in sorted order
for (Integer key : mapIndex.keySet())
{
Integer value = mapIndex.get(key);
findanswer(key,value);
}
print();
}
}