确定是否存在具有顶点度数序列的图形(s = s1,s2 ... sn)。 什么是解决此问题的最佳和最优化的算法。
Input:
the first line contains `t<100` - amount of sequnces.
the second line contains value `n <= 1000000`(length of a sequence).
the third line contains contains `n` non-negative integer numbers. And so on.
Output:
if the graph can exist print "yes" otherwise print "no".
For example:
Input:
3
5
1 2 3 2 1
4
3 3 2 2
3
1 3 2
Output:
No
Yes
Yes
最长执行时间应为0.4秒。 这是我的代码(如果奇数顶点的数量是偶数,则图表存在):
import java.util.Scanner;
public class Main {
public static final Scanner in = new Scanner(System.in);
public static void isGraph (int []a, int n) {
int k=0;
for(int i=0; i< n; i++) {
if(a[i] %2 != 0) {
k++;
}
}
if(k%2 == 0)
System.out.println("Yes");
else
System.out.println("No");
}
public static void main(String[] args) throws Exception{
double t1 = System.nanoTime();
int n;
int []a;
int t = Integer.parseInt(in.nextLine());
while(t-- > 0) {
n = in.nextInt();
a = new int[n];
for(int i=0; i<n; i++)
a[i] = in.nextInt();
isGraph(a,n);
}
System.out.println(System.nanoTime() - t1);
}
}
但该程序的执行时间超过0.4秒。我的运行时间超出了。我如何优化代码并加快运行时间。可能还有另一种算法来解决这个任务,请帮帮我。
答案 0 :(得分:2)
我想我有更快捷的方式。请验证这一点。如果你担心偶数/奇数的最终结果,那么似乎没有理由跟踪k计数器。您可以保持运行顺序是偶数还是奇数的动态值:
public static void isGraph (int []a, int n) {
int k = 0;
for(int i=0; i< n; i++) {
k += a[i] & 1;
}
if(k%2 == 0)
System.out.println("Yes");
else
System.out.println("No");
}
这可能有助于你的阅读:我没有经验,但是我从竞赛网站上得到了它:
阅读速度缓慢:
/** Read count integers using Scanner */
static int scanInteger(int count) {
Scanner scanner = new Scanner(input);
int last = 0;
while (count-- > 0) {
last = scanner.nextInt();
}
return last;
}
更快的方式:
static int readIntegers(int count)
throws IOException {
BufferedReader reader = new BufferedReader(
new InputStreamReader(input) );
StringTokenizer tokenizer = new StringTokenizer("");
int last = 0;
while (count-- > 0) {
if (! tokenizer.hasMoreTokens() ) {
tokenizer = new StringTokenizer(reader.readLine());
}
last = Integer.parseInt(tokenizer.nextToken());
}
return last;
}
编辑:展示如何避免阶段1为读取循环的两个阶段,阶段2为算法:
public static void main(String[] args) throws Exception{
double t1 = System.nanoTime();
int n;
// int []a; // Not necessary
int t = Integer.parseInt(in.nextLine());
while(t-- > 0) {
n = in.nextInt();
// a = new int[n]; // Not necessary
int k = 0;
int a;
for(int i=0; i<n; i++) {
a = in.nextInt();
k += a & 1;
}
// isGraph(a,n); // Not necessary
if(k % 2 == 0)
System.out.println("Yes");
else
System.out.println("No");
}
System.out.println(System.nanoTime() - t1);
}
答案 1 :(得分:0)
可能还有另一种解决此任务的算法
那不是问题(IMO)。
提示1:既然您事先知道序列的长度,就可以创建数组并以比这更快的速度解析序列:
a = Arrays.stream(s.split(" ")).mapToInt(Integer::parseInt).toArray();
(Java 8+流很优雅,但它们不是最快的方式。)
提示2:使用Scanner
可能比读取字符串并解析它们更快。
提示3:您可能完全避免创建数组。 (这将是不良的编码实践IMO ...但如果性能至关重要......)