给定一个字符串,找到具有相同元音和辅音数量的最长子字符串。
澄清:我不确定,我们是否可以生成新字符串,或者子字符串必须是原始字符串的一部分?到目前为止,我有这个,
代码段:
SetStreamTick
编辑我让计数有效,但我该如何创建子字符串?
答案 0 :(得分:3)
这可以使用" net"在 O(n)时间和空间中解决。由this answer计算的值结合以下观察结果:
要看到这一点,请注意告诉我们子串s [i .. j]是我们正在寻找的那种情况的条件
net[i .. j] = 0.
将net [1 .. i-1]添加到此等式的两边给出
net[1 .. i-1] + net[i .. j] = net[1 .. i-1]
然后用LHS简化到
net[1 .. j] = net[1 .. i-1]
这意味着我们可以创建一个包含两个条目的表(第一个看到的位置和看到的最后一个位置),我们可以在计算净值的运行总和时获得每个可能的不同值。这个运行总数的范围可以低至-n(如果每个字符都是辅音)或高至n(如果每个字符都是元音),那么总共最多有2n + 1个不同的总和,所以我们&#39 ;在我们的表中需要那么多行。然后,我们从左到右遍历字符串,计算一个运行的总净值,并更新表中对应于当前运行总计的对,注意每当此更新产生一个新的最大长度子字符串时。在伪代码中,使用从零开始的数组索引并使用单独的数组来保存每对中的元素:
最大长度范围将在(bestFirst,bestLast)中返回,或者如果不存在此类范围,则这些变量都将为-1。
我记得在过去的某个地方看到过这个解决方案,或者一个非常类似的解决方案 - 如果有人能找到它,我很乐意链接到它。
答案 1 :(得分:2)
要找到辅音和元音数相等的最长子串,请开始查找最大长度的子串,并稳定减少所需的长度,直到找到符合条件的子串为止。
这样可以使操作短路。
public static String findLongestSubstring(String str) {
for (int len = str.length(); len >= 2; len--) {
for (int i = 0; i <= str.length() - len; i++) {
String substr = str.substring(i, i + len);
int vowels = countVowels(substr);
int consonants = len - vowels;
if (vowels == consonants) {
return substr;
}
}
}
return "";
}
private static int countVowels(String str) {
return str.replaceAll("[^AEIOUaeiou]+", "").length();
}
答案 2 :(得分:2)
以下是我在O(n^2)
时间内运行的原始答案的更新版本。它通过使用技巧来实现这一点,即跟踪单个变量(称为“网络”),该变量跟踪元音和辅音数量之间的差异。当此数字为零时,给定的子字符串是平衡的。
在最坏的情况下,需要O(n^2)
迭代每个可能的子字符串,但是不需要额外的时间检查字符串和元音的每个子字符串,因为它使net
保持最新每个新步骤选择一个子字符串。因此,它将复杂性从O(n^3)
降低到O(n^2)
。
public String findLongestSubstring(String input) {
String longest = "";
for (int window = inputz.length(); window >=2; --window) {
String substr = input.substring(0, window);
String consonants = input.substring(0, window).toLowerCase()
.replaceAll("[aeiou]", "");
int vowelCount = input.substring(0, window).length() - consonants.length();
int consonantCount = consonants.length();
int net = vowelCount - consonantCount;
for (int i=window; i <= input.length(); ++i) {
if (net == 0) {
longest = input.substring(i-window, i);
return longest;
}
// no-op for last window
if (i == input.length()) break;
// update tally by removing high character
if ("aeiou".indexOf(input.charAt(i)) != -1) {
++net;
}
else {
--net;
}
// update tally by adding low character
if ("aeiou".indexOf(input.charAt(i-window)) != -1) {
--net;
}
else {
++net;
}
}
}
return longest;
}
答案 3 :(得分:0)
我认为这可能是你的任务的决定(不是太长的输入字符串):
import org.junit.Test;
/**
* Created by smv on 19/09/16.
*/
public class MainTest {
public static boolean isVowel(char c) {
return "AEIOUaeiou".indexOf(c) != -1;
}
public int getVowelCount(String str) {
int res = 0;
for(int i=0; i < str.length(); i++){
if(isVowel(str.charAt(i))) {
res++;
}
}
return res;
}
public int getConsonantCount(String str) {
int res = 0;
for(int i=0; i < str.length(); i++){
if(!isVowel(str.charAt(i))) {
res++;
}
}
return res;
}
@Test
public void run() throws Exception {
String string = "aasdaasggsertcwevwertwe";
int lengthOfString = string.length();
String maxSub = "";
int maxSubLength = 0;
// find all substrings of given string
for( int c = 0 ; c < lengthOfString ; c++ )
{
for( int i = 1 ; i <= lengthOfString - c ; i++ )
{
String sub = string.substring(c, c+i);
// comparing count vowels and consonants
if (getVowelCount(sub) == getConsonantCount(sub)) {
if (sub.length() > maxSubLength) {
maxSub = sub;
maxSubLength = sub.length();
}
}
}
}
System.out.println(maxSub);
}
}
答案 4 :(得分:0)
当然,这里的要求非常模糊。它没有提到输入中是否包含数字或其他键。我假设起始指数为零,因为计数在该点相等。
Scanner scanner = new Scanner(System.in);
String string = new String(scanner.next());
int lengthOfString = string.length();
int vowelCount = 0;
int consCount = 0;
int maxIndex = -1;
for(int i = 0; i < lengthOfString; i++)
{
System.out.println("Char: " + string.charAt(i));
if(string.charAt(i) == 'u' || string.charAt(i) == 'e' || string.charAt(i) == 'i'
|| string.charAt(i) == 'o' || string.charAt(i) == 'a')
{
vowelCount++;
}
else
{
consCount++;
}
if(vowelCount == consCount)
{
System.out.println("count equal with: " + string.substring(0, (i + 1)));
maxIndex = i + 1;
}
}
if(maxIndex > 0)
{
System.out.println("Longest sub string with equal count of vowels and consonants is: "
+ string.substring(0, maxIndex));
}
else
{
System.out.println("No substring existed with equal count of vowels and consonants.");
}