【问题标题】:Number of substrings of string which has three vowels具有三个元音的字符串的子串数
【发布时间】:2017-07-09 05:58:30
【问题描述】:

我参加了关于hackerearth的编码挑战,我被问到以下问题。

Alice 和 Bob 正在玩一个游戏,其中 Bob 给 Alice 一个长度为 NN 的由小写英文字母组成的字符串 SS,并要求她计算该字符串的子字符串的数量,该字符串正好包含 3 个元音。

这是我的代码

import java.io.BufferedReader;
import java.io.InputStreamReader;


class TestClass1{
public static void main(String args[] ) throws Exception {

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String line = br.readLine();
    int N = Integer.parseInt(line);


    String stringArray[]=new String[N];

    for (int i = 0; i < N; i++) {
        int len = Integer.parseInt(br.readLine());
        stringArray[i]=br.readLine();     
    }

    for (int i = 0; i < N; i++) {
      System.out.println(determineNumberOfSubstring(stringArray[i]));
    }


}
public static int determineNumberOfSubstring(String str)
{
    int numberOfSubstring=0;
    for(int i=0;i<str.length();i++)
    {
        int ctr=0;
        for(int j=1;j<str.length()-i;j++)
        {
             String subString = str.substring(i,i+j);
             if(subString.length()<3)
             {
                 continue;
             }
            if(subString.contains("a")||subString.contains("e")||subString.contains("i")||subString.contains("o")||subString.contains("u")
                ||subString.contains("A")||subString.contains("E")||subString.contains("I")||subString.contains("O")||subString.contains("U"))
            {
                ctr+=3;
            }
        }
        if(ctr==3){
            numberOfSubstring++;
        }

    }
    return numberOfSubstring;
}

} 我正在超出上述代码的时间限制。任何人都可以帮助我如何优化它。

更新1

代码按照@GhostCat 逻辑,需要测试,不是最终代码。

class TestClass1{
public static void main(String args[] ) throws Exception {

BufferedReader br = new BufferedReader(new         InputStreamReader(System.in));
    String line = br.readLine();
    int N = Integer.parseInt(line);
    String stringArray[]=new String[N];

    for (int i = 0; i < N; i++) {
        int len = Integer.parseInt(br.readLine());
        stringArray[i]=br.readLine();     
    }

    for (int i = 0; i < N; i++) {
      System.out.println(determineNumberOfSubstring(stringArray[i]));
    }
}
public static int determineNumberOfSubstring(String str)
{
    int numberOfSubstring=0;
    int ctr=0;
    int subStringStart=0;
    Stack<String> s = new Stack<String>();
    for(int i=0;i<str.length();i++)
    {
        if(isVowel(str.charAt(i)))
            ctr++;
        if(ctr==3)
        {
            numberOfSubstring++;
            ctr=0;
            if(s.empty())
                s.push(str.substring(0,i));
            else
                s.push(new String(s.peek().substring(1,i+1)));
            i=str.indexOf(s.peek().charAt(1))-1;
        }
    }
    return numberOfSubstring;
}
private static boolean isVowel(char c) {
     if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'
             ||c=='A'||c=='E'||c=='I'||c=='O'||c=='U')
         return true;
    return false;
}

}

【问题讨论】:

  • @ghostcat 感谢您的帮助,目前我处于医疗紧急状态。我会尽快回复这个问题。
  • 对您的更新的一些想法:使用isVowel() 是一个明显的改进,因为您的代码现在也更易于阅读。例如,您可以检查使用 Character.toLowerCase() 是否“更好”;这将比较次数减少了一半。或者如前所述,创建一个Set&lt;Character&gt; vowels = new HashSet&lt;&gt;(Arrays.asList('A, 'a', ...)) 并使用它的 contains() 方法。我不得不承认我没有得到你的堆栈解决方案的全部范围(我不确定你是否需要那个 - 所以你可以考虑让它更短;-) ...最后:请记住,这不是导师服务;所以:当你有更多时
  • 问题,然后请提出一个新问题(或者我们谈论我为其他地方的支持提供导师建议 ;-)

标签: java string algorithm data-structures substring


【解决方案1】:

提示:您的代码正在为每个小写和大写元音迭代整个子字符串。这发生在一个循环中的循环中。

改为:使用 ONE 循环遍历输入字符串的字符。然后通过检查一组字符(包含那些有效的元音)来检查每个位置是否是元音。您需要的最后一件事:一个简单的“滑动”窗口;比如:当你发现三个元音时,你可以增加你的计数器;然后“忘记”你刚刚找到的三个元音中的第一个;比如:

a x e y i --> vowels a/e/i give one substring
  x e y i ... and you look out for the next substring e/i/... now

实际实现留给读者练习......

长话短说:这个计数可以通过处理您的输入一次来计算。您的代码不止一次地迭代无数次。嗯,不是无数,而是 N * N * 更多。

(需要注意的一件事:使用Set&lt;Character&gt; 时,将char 值转换为Character 对象时要精确;您也希望尽量减少这种情况发生;因为那是相当昂贵的操作)

【讨论】:

  • 感谢@GhostCat。解释非常直观明了。我正在发布我迄今为止编码的任何内容。这未经测试,将尽快更新。
【解决方案2】:
快乐编码######(如果有用,请点赞)

Que:计算可能的子字符串在给定字符串中恰好包含 3 个元音 我在 O(n) 中的方法:

#include<bits/stdc++.h>
using namespace std;

int main()
{

        string s;
        cin>>s;
    vector<long long int>idex;

    idex.push_back(-1);
    for(int i=0;i<n;i++)
    {
        if(s[i]=='a' || s[i]=='e' || s[i]=='i' || s[i]=='o' || s[i]=='u')
        {
            idex.push_back(i);
        }
    }
    idex.push_back(n);
    if(idex.size()<5)
    {
        cout<<0<<endl;
    }
    else
    {
        long long int ans=0;
        for(int i=1;i<=idex.size()-4;i++)
        {
           ans+=(idex[i]-idex[i-1])*(idex[i+3]-idex[i+2]);
        }
        cout<<ans<<endl;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-13
    • 1970-01-01
    • 2016-05-03
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    • 1970-01-01
    相关资源
    最近更新 更多