我在编译时由于超时错误而终止。请帮助我
给出两个字符串,确定它们是否共享一个公共子字符串。子字符串可能只有一个字符。
例如,单词“ a”,“ and”,“ art”共享公共子字符串“ a”。 “ be”和“ cat”这两个词不共享子字符串。
输入格式
第一行包含一个整数,即测试用例的数量。
以下几对线如下:
第一行包含字符串s1。 第二行包含字符串s2。
输出格式
对于每对字符串,返回YES或NO。
我在Java中的代码
public static void main(String args[])
{
String s1,s2;
int n;
Scanner s= new Scanner(System.in);
n=s.nextInt();
while(n>0)
{
int flag = 0;
s1=s.next();
s2=s.next();
for(int i=0;i<s1.length();i++)
{
for(int j=i;j<s2.length();j++)
{
if(s1.charAt(i)==s2.charAt(j))
{
flag=1;
}
}
}
if(flag==1)
{
System.out.println("YES");
}
else
{
System.out.println("NO");
}
n--;
}
}
}
任何提示?
答案 0 :(得分:0)
超时的原因可能是:比较每个长度为1.000.000个字符的两个字符串,您的代码始终需要进行1.000.000 * 1.000.000比较。
有一个更快的算法,只需要2 * 1.000.000比较即可。您应该改用更快的算法。其基本思想是:
Java已经提供了您所需的BitSet数据类型。它的用法如下:
BitSet seenInS1 = new BitSet();
seenInS1.set('x');
seenInS1.get('x');
答案 1 :(得分:0)
由于您担心执行时间,因此如果它们给您期望的字符范围(例如'a'
至'z'
),您可以像这样高效地解决它:
import java.util.Arrays;
import java.util.Scanner;
public class Whatever {
final static char HIGHEST_CHAR = 'z'; // Use Character.MAX_VALUE if unsure.
public static void main(final String[] args) {
final Scanner scanner = new Scanner(System.in);
final boolean[] characterSeen = new boolean[HIGHEST_CHAR + 1];
mainloop:
for (int word = Integer.parseInt(scanner.nextLine()); word > 0; word--) {
Arrays.fill(characterSeen, false);
final String word1 = scanner.nextLine();
for (int i = 0; i < word1.length(); i++) {
characterSeen[word1.charAt(i)] = true;
}
final String word2 = scanner.nextLine();
for (int i = 0; i < word2.length(); i++) {
if (characterSeen[word2.charAt(i)]) {
System.out.println("YES");
continue mainloop;
}
}
System.out.println("NO");
}
}
}
The code was tested to work with a few inputs。
这使用快速数组而不是较慢的集合,并且在整个程序运行过程中仅创建一个非String
对象(Scanner
除外)。它还以O(n)时间而不是O(n²)时间运行。
唯一可能比数组 快的事物是the BitSet
Roland Illig mentioned。
如果您想完全落伍,还可以通过以下方式加快速度:
System.in.read(buffer)
与可重用的Scanner
缓冲区一起使用,从而跳过String
和所有这些byte[]
对象的创建int
解析器仅假设它获取有效的非负数{来跳过标准的过程,即花时间检查并正确处理第一行的负数和无效输入。 {1}}后跟换行符答案 2 :(得分:0)
有多种方法可以解决此问题,但是在线性时间内解决此问题有些棘手。
尽管如此,这个问题仍可以在linear
时间内解决。只需以更棘手的方式应用KMP algorithm
。
假设您有2个字符串。首先找到两个字符串的长度。说string 1
的长度大于string 2
。将string 1
设为text
,将string 2
设为pattern
。如果字符串的长度为n
,而模式的长度为m
,则上述问题的时间复杂度将为O(m+n)
,比O(n^2)
快得多。>
在此问题中,您需要修改KMP algorithm
以获得所需的结果。
只需修改KMP
public static void KMPsearch(char[] text,char[] pattern)
{
int[] cache = buildPrefix(pattern);
int i=0,j=0;
while(i<text.length && j<pattern.length)
{
if(text[i]==pattern[j])
{System.out.println("Yes");
return;}
else{
if(j>0)
j = cache[j-1];
else
i++;
}
}
System.out.println("No");
return;
}
答案 3 :(得分:0)
public String twoStrings(String sOne, String sTwo) {
if (sOne.equals(sTwo)) {
return "YES";
}
Set<Character> charSetOne = new HashSet<Character>();
for (Character c : sOne.toCharArray())
charSetOne.add(c);
Set<Character> charSetTwo = new HashSet<Character>();
for (Character c : sTwo.toCharArray())
charSetTwo.add(c);
charSetOne.retainAll(charSetTwo);
if (charSetOne.size() > 0) {
return "YES";
}
return "NO";
}
这必须工作。经过大量输入测试。
答案 4 :(得分:0)
Python3
def twoStrings(s1, s2):
flag = False
for x in s1:
if x in s2:
flag = True
if flag == True:
return "YES"
else:
return "NO"
if __name__ == '__main__':
q = 2
text = [("hello","world"), ("hi","world")]
for q_itr in range(q):
s1 = text[q_itr][0]
s2 = text[q_itr][1]
result = twoStrings(s1, s2)
print(result)
答案 5 :(得分:0)
下面是我克服上述相同的HackerRank挑战的方法
static String twoStrings(String s1, String s2) {
String result="NO";
Set<Character> set1 = new HashSet<Character>();
for (char s : s1.toCharArray()){
set1.add(s);
}
for(int i=0;i<s2.length();i++){
if(set1.contains(s2.charAt(i))){
result = "YES";
break;
}
}
return result;
}
它通过了所有测试用例,没有超时问题。
答案 6 :(得分:-1)
解决此问题涉及两个概念。
-理解单个字符是有效的子字符串。
-推断我们只需要知道两个字符串有一个公共子字符串-我们就不需要知道该子字符串是什么。
因此,解决此问题的关键是确定两个字符串是否具有相同的字符。
为此,我们创建了两个集合a和b,其中每个集合都包含出现在以其命名的字符串中的唯一字符。
因为集合26不会存储重复的值,所以我们知道集合的大小永远不会超过英文字母的大小。
此外,这些集合的尺寸很小,因此可以很快找到相交点。
如果两个集合的交集为空,则在新行上打印NO;如果两个集合的交集不为空,则我们知道字符串并共享一个或多个公共字符,并在新行上打印“是”。
在代码中,可能看起来像这样
import java.util.*;
public class Solution {
static Set<Character> a;
static Set<Character> b;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
for(int i = 0; i < n; i++) {
a = new HashSet<Character>();
b = new HashSet<Character>();
for(char c : scan.next().toCharArray()) {
a.add(c);
}
for(char c : scan.next().toCharArray()) {
b.add(c);
}
// store the set intersection in set 'a'
a.retainAll(b);
System.out.println( (a.isEmpty()) ? "NO" : "YES" );
}
scan.close();
}
}
答案 7 :(得分:-1)
static String twoStrings(String s1, String s2) {
for (Character ch : s1.toCharArray()) {
if (s2.indexOf(ch) > -1)
return "YES";
}
return "NO";
}