我今天必须接受一次面试,问题是获取字典上最小和最大的子串(换句话说,按名称排序)。
Link - 完成函数SmallestAndLargestSubstring,它接受由小写英文字母(a-z)组成的字符串S作为其参数,并返回按字典顺序排列的最小和最大子串,以元音开头并以辅音结束。
我的算法通过了基本的测试用例,但大多数其他测试用例失败了。它不是最有效的代码,但它编写速度最快。
static String[] SmallestAndLargestSubstring(String s) {
ArrayList<Character> vowelList = new ArrayList<Character>();
vowelList.add('a');
vowelList.add('e');
vowelList.add('i');
vowelList.add('o');
vowelList.add('u');
ArrayList<Character> consonantList = new ArrayList<Character>();
for (char c='a'; c<='z'; c++) {
if (!vowelList.contains(c))
consonantList.add(c);
}
ArrayList<String> substringList = new ArrayList<String>();
for (int i=0; i<s.length(); i++) {
char c = s.charAt(i);
if (vowelList.contains(c)) {
String substring = "";
substring+=c;
for (int j=i+1; j<s.length(); j++) {
char c2 = s.charAt(j);
substring+=c2;
if (consonantList.contains(c2)) {
substringList.add(substring);
}
}
}
}
Collections.sort(substringList);
String[] outputAdapter = new String[2];
outputAdapter[0]=substringList.get(0);
outputAdapter[1]=substringList.get(substringList.size()-1);
return outputAdapter;
}
无论如何,我想弄明白我哪里出错了,所以我反过来设计了测试用例来弄清楚传入的输入是什么,希望我能够弄清楚我的算法出了什么问题。< / p>
这是我发现的内容,这些是我的答案(根据测试用例,这是错误的)。
输入
String s =“azizezozuzawwwwwwwwwuzzzzzzzzabbbbbbbaaaabbbboiz”
我的回答
smallest =“aaaab”;
largest =“uzzzzzzzzabbbbbbbaaaabbbboiz”;
但是对于我的生活,我无法弄清楚我的错误在哪里。这是我的子串的完整列表,从最小到最大排序。 Link to sorted results
在过去的3个小时里绞尽脑汁。如果有人能弄明白我的错误,我将不胜感激。
编辑:这是另外3个测试用例。我的答案符合这些测试用例的答案。
string =“aba”;最小=“ab”;最大=“ab”;
string =“aab”;最小=“aab”;最大=“ab”;
string =“abababababbaaaaaaaaaaaaaaz”;最小=“aaaaaaaaaaaaaaz”;最大=“az”;
答案 0 :(得分:0)
/*
It is the Basic code to Obtain Substring which start with Vowel and End up with Consonant. It is going to print on the Basis of Name Comparable, The first and the Last Substring in the List.Similarly we can achieve on the basis of length, the firt and last Substring using different comparator function.
*/
public class StringSubsequencesStartVowelEndConsonant {
static List<String> subsequence = new LinkedList<>();
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter the String:\n");
String string = in.next();
findSubstring(string);
}
private static void findSubstring(String string) {
for(int i=0;i<string.length();i++){
if(isVowel(string.charAt(i))){
for(int j=string.length()-1;j>=i;j--){
if(isConsonant(string.charAt(j))){
String subString = string.substring(i,j+1);
subsequence.add(subString);
}
}
}
}
Collections.sort(subsequence);
for(String str : subsequence){
System.out.print(str+" ");
}
System.out.println();
System.out.println(subsequence.get(0));
System.out.println(subsequence.get(subsequence.size()-1));
}
private static boolean isConsonant(char chars) {
return !(chars=='a'|| chars=='e'||chars=='i'||chars=='o'||chars=='u');
}
private static boolean isVowel(char chars) {
return (chars=='a'|| chars=='e'||chars=='i'||chars=='o'||chars=='u');
}
}
答案 1 :(得分:0)
好吧,您可以遍历字符串,同时标记在当前元素上遇到的最接近最小和最接近缩影的子字符串的起点和终点的索引。您可以通过这种方式获得O(n)解决方案。
遍历时保持当前正在分析的子字符串的标记。
另外,每当我们遇到一个与当前子字符串开头的元音相同的新元音时,我们可以跳到新的位置,而对于最大的lex,我们想扩展我们的子字符串。
有很多检查,遵循以下代码会更加详细。
def f(s):
ind_s, ind_l = -1, -1
st_s, st_l = -1, -1
end_s, end_l = -1, -1
vo = ['a', 'e', 'i', 'o', 'u']
for i, c in enumerate(s):
if c in vo:
if ( ind_s == -1 and ( (st_s == -1) or (c <= s[st_s]) ) ) or ( c <= s[ind_s] ):
ind_s = i
if ( ind_l == -1 and ( (st_l == -1) or (c >= s[st_l]) ) ) or ( c >= s[ind_l] ):
ind_l = i
else:
if ind_s != -1:
if st_s == -1 or end_s == -1:
st_s, end_s, ind_s = ind_s, i, -1
else:
if i - ind_s > end_s - st_s:
ind_s = -1
elif c < s[st_s + i - ind_s]:
st_s, end_s, ind_s = ind_s, i, -1
if ind_l != -1:
if st_l == -1 or end_l == -1:
st_l, end_l, ind_l = ind_l, i, -1
else:
if i - ind_l > end_l - st_l:
st_l, end_l = ind_l, i
elif c > s[st_l + i - ind_l]:
st_l, end_l = ind_l, i
elif c < s[st_l + i - ind_l]:
ind_l = -1
return s[st_s:end_s + 1], s[st_l:end_l + 1]
if __name__ == '__main__':
print ( f("aebbebbebbebgeb") )