Array rotation TLE (Time Limit Exceeded) - java

I am really confused why my java code is not working it is giving TLE on Code Monks on Hacker Earth.
Here is the link to the 1
Link to Question
the first question MONK AND ROTATION
import java.util.Scanner;
class TestClass {
static int[] ar=new int[100001];
public static void main(String args[] ){
Scanner in=new Scanner(System.in);
byte t=in.nextByte();
while(t-->0){
int n=in.nextInt();
int k=in.nextInt()%n;
for(int i=0;i<n-k;i++)
ar[i]=in.nextInt();
for(int i=0;i<k;i++)
System.out.print(in.nextInt()+" ");
for(int i=0;i<n-k;i++)
System.out.print(ar[i]+" ");
System.out.println();
}
}
}
I don't know why is it giving TLE I think there is some infinite loop going.
the question at the site is-
Monk and Rotation
Monk loves to perform different operations on arrays, and so being the principal of HackerEarth School, he assigned a task to his new student Mishki. Mishki will be provided with an integer array A of size N and an integer K , where she needs to rotate the array in the right direction by K steps and then print the resultant array. As she is new to the school, please help her to complete the task.
Input:
The first line will consists of one integer T denoting the number of test cases.
For each test case:
The first line consists of two integers N and K, N being the number of elements in the array and K denotes the number of steps of rotation.
The next line consists of N space separated integers , denoting the elements of the array A.
Output:
Print the required array.
Constraints:
1<=T<=20
1<=N<=10^5
0<=K<=10^6
0<=A[i]<=10^6
Sample Input
1
5 2
1 2 3 4 5
Sample Output
4 5 1 2 3
Explanation
Here T is 1, which means one test case.
denoting the number of elements in the array and , denoting the number of steps of rotations.
The initial array is:
In first rotation, 5 will come in the first position and all other elements will move to one position ahead from their current position. Now, the resultant array will be
In second rotation, 4 will come in the first position and all other elements will move to one position ahead from their current position. Now, the resultant array will be
Time Limit: 1.0 sec(s) for each input file
Memory Limit: 256 MB
Source Limit: 1024 KB

I'm not sure about the correctness of your solution, but try to use StreamTokenizer or BufferedReader instead of Scanner. Scanner is too slow and may result in TLE when you need to read a lot of data.

Reduce the number of reads and writes from/to System.in and System.out.
Look at the following solution
Scanner scanner = new Scanner(System.in);
int noOfTestCases = scanner.nextInt();
for (int i = 0; i < noOfTestCases; i++) {
int arraySize = scanner.nextInt();
int noOfRotations = scanner.nextInt();
noOfRotations = noOfRotations % arraySize;
scanner.nextLine();
String inputString = scanner.nextLine();
String[] inputStringArray = inputString.split(" ");
StringBuffer sb = new StringBuffer();
for (int j = 0; j < arraySize; j++) {
sb.append(inputStringArray[(arraySize + j - noOfRotations) % arraySize] + " ");
}
System.out.print(sb);
System.out.println("");
}

import java.util.*;
public class temp {
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while(t-->0){
int n = sc.nextInt();
int k = sc.nextInt();
int p = 0;
int ar[] = new int[n];
for(int i=0;i<n;i++){
ar[i] = sc.nextInt();
}
k %= n;
for(int i=0;i<n;i++){
p = ar[(i+(n-k))%n];
System.out.print(p+" ");
}
System.out.println();
}
}
}
Though I have not used a big sized array in the starting, this code is working fine for all test cases.
Try this one.

Think from a different perspective. Instead of splitting the string and converting it into an array and applying the iterative logic, we can apply a different logic.
The trick is you just need to find the position of the input string where we have to split only once.
By that I mean,
input=>
6 2       //4 is the length of numbers and 2 is the index of rotation
1 2 3 4 5 6     //array (take input as a string using buffered reader)
Here, we just need to split the array string at the 2nd last space i.e. 4th space. So the output can be achieved by just splitting the string once-
5 6 1 2 3 4
first split- 5 6 + space + second split- 1 2 3 4
This logic worked for me and all the test cases passed.
Also don't forget to cover the corner case scenario when array input string is just one number.
Code Snippet-
int count=0;
for(int k=0; k<arr.length(); k++) {
if(arr.charAt(k)==' ')
count++;
if(count==size-rot) {
System.out.println(arr.substring(k+1,arr.length())
+ " " + arr.substring(0,k));
break;
}
}

Problem is in the System.out.print() call that is inside the for-loop. Thats a fairly heavy call and if called too many times and creates an overhead. This solution works:
//import for Scanner and other utility classes
import java.util.*;
class TestClass {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String input = s.nextLine();
int noOfTests = Integer.parseInt(input);
for (int t = 0; t < noOfTests; t++) {
input = s.nextLine();
String[] str = input.split(" ");
int sizeOfArray = Integer.parseInt(str[0]);
int noOfRotations = Integer.parseInt(str[1]);
String strIntegerArray = s.nextLine();
String[] array = strIntegerArray.split(" ");
printRightRotatedArray(array, noOfRotations, strIntegerArray.length());
}
}
static void printRightRotatedArray(String[] array, int noOfRotations, int lengthOfStr) {
int len = array.length;
int noOfAcutalRotations = noOfRotations % len;
int startingIndex = len - noOfAcutalRotations;
StringBuilder sb = new StringBuilder(lengthOfStr+1);
for (int i = 0; i < len; i++) {
sb.append(array[(startingIndex + i) % len]);
sb.append(" ");
}
System.out.println(sb);
}
}

putting all into string buffer and print at the end worked for me.
class TestClass {
public static void main(String args[] ) throws Exception {
//BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(br.readLine());
StringBuilder sb = new StringBuilder();// output
for(int i=0;i<t;i++){
String [] nk=br.readLine().split(" ");
int n= Integer.parseInt(nk[0]);
int k=Integer.parseInt(nk[1]);
String [] a=br.readLine().split(" ");
int split=n-(k%n);
for (int j = split; j < a.length; j++) {
sb.append(a[j]);
sb.append(' ');
}
for (int j = 0 ; j < split; j++) {
sb.append(a[j]);
sb.append(' ');
}
sb.append("\n");
}
System.out.println(sb);
}
}

Related

Reading a string splitting it and assigning values to 2D array in JAVA

I am trying to split a string with " "(space) and assigning each value on row to each respective array.
The input file contains:
4
2 2
1 3
4 7
3 4
The first line of the file has a single integer value N which is number of jobs.
The next N lines will represent a job, each with 2 values.
How do I start reading from second line from a Input file?
I want to split from Second line and assign it to 2D array. So if (2,2) is there on second line, then 2 should be assigned to array[0][0] and the other 2 to array[0][1]. For next line 1 should be assigned to array[1][0] and 3 should be assigned to array[1][1].
int num = scan.nextInt(); // taking number of jobs from first line
int[][] array = new int[num][num];
while (scan.hasNext()) //It reads till file has next line
{
String str = scan.nextLine();
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
array[i][j] = scan.nextInt();
}
}
}
Had done till here, couldn't figure out further.
int[][] array = new int[num][num];
Wrong dimensions of the array, for N = 4 you create array of 4 * 4, not 4 * 2.
Since the number of columns is fixed in your case, you should create array as new int[num][2] and update reading of the data accordingly.
String str = scan.nextLine();
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
array[i][j] = scan.nextInt();
}
}
Reading a line just to skip it may be redundant if you use Scanner to read the integer numbers using nextInt. So actually you do NOT need to read the data line by line, then split each line into String parts, and convert each part into a number because Scanner class takes care of it.
Also, the innermost loop tries to read N numbers per array row, while it's better to refer actual length of the array in the row.
Thus, it should be ok just to read the data according to the task using Scanner only:
int num = scan.nextInt(); // taking number of jobs from the first line
// preparing array of N rows and 2 columns
int[][] array = new int[num][2];
for (int i = 0; i < num; i++) {
for (int j = 0; j < array[i].length; j++) { // reading 2 ints per row
array[i][j] = scan.nextInt();
}
}
You can make it a lot easier by just ignoring the first line and letting Java do the hard work:
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
import java.util.Arrays;
public class FileToArray {
public static void main(String[] args) {
try {
try (Stream<String> stream = Files.lines(Path.of("arr.txt"))) {
String[][] nums = stream.skip(1).map(s -> s.split(" ")).toArray(String[][]::new);
System.out.println(Arrays.deepToString(nums));
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}

Moving Average Using User-Input Array

I need to write a program that calculates a moving average by a user inputted array. The first element of the array is the window size, and the input is terminated by a 0. The output values are printed with two digits after the decimal point.
Example input: 3 2 4 7 7 8 11 12 0
Corresponding Output: 4.33 6.00 7.33 8.67 10.33
(4.33 is average of 2,4,7 and 6 is average of 4,7,7 etc.)
Here's my code so far:
package movingaverage;
import java.util.Scanner;
public class MovingAverage {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
int sum = 0;
for (int i = 0; i < n; i++) {
sum += arr[i];
}
avg[0] = sum / 5;
int j = 1;
for (int i = 5; i < arr.length; i++) {
sum = sum + arr[i] - arr[i - 5];
avg[j++] = sum / 5;
}
}
}
I think I have the loop right, but I'm not sure how to get the array to end at 0.
This is a possible solution.
public class Test
{
private static final Scanner SCANNER;
static {
SCANNER = new Scanner(System.in);
}
public static final void main(final String... args) {
final String[] numbers = SCANNER.nextLine().trim().split(" ");
final int consideredElements = Integer.parseInt(numbers[0]);
float sum = 0;
int value = 0;
for (int i = 1; i < numbers.length; i++) {
sum = 0;
for (int k = 0; k < consideredElements; k++) {
value = Integer.parseInt(numbers[i + k]);
if (value == 0) {
return;
}
sum += value;
}
System.out.println(new BigDecimal(sum / consideredElements).setScale(2, RoundingMode.HALF_EVEN));
}
}
}
First, you are using 5 in a couple of places in your program, I see no justification for that. Could it be that your expectation of user input lead you to put 5 where the number you really should use, depends on user input? Maybe you should use the window size instead? I’m guessing a bit here.
Next, as #lppEdd pointed out, you are not reading the numbers from your input — only the window size.
Next, you are declaring your array of size n, which I believe was your window size, not your array size. I believe the real solution to this problem is using better and more explanatory variable names.
Your code does not compile since you have not declared the array avg that you try to store your moving average into.
Fifth, when you want your average as a double, you need to convert to double before dividing (this is a classic pitfall that has already generated many questions on Stack Overflow).
I hope this gets you a couple of steps further.

Java Random Utility Generating Too Many 0's And Static Numbers

The line birthdays[j] = rnd.nextInt(365); seems to generate extra 0's in the int[] birthdays array. It also seems to add an EXTRA 0 into the array and generate static values depending on how many simulations I run and how many birthdays I generate. For instance, if I do 5 simulations and enter a 3 for the number of people in each simulation's "birthday pool" I always get an array of [0, 0, 289, 362].
Any help understanding the problem would be greatly appreciated.
public static void main(String[] args) {
System.out.println("Welcome to the birthday problem Simulator\n");
String userAnswer="";
Scanner stdIn = new Scanner(System.in);
do {
int [] userInput = promptAndRead(stdIn);
double probability = compute(userInput[0], userInput[1]);
// Print results
System.out.println("For a group of " + userInput[1] + " people, the probability");
System.out.print("that two people have the same birthday is\n");
System.out.println(probability);
System.out.print("\nDo you want to run another set of simulations(y/n)? :");
//eat or skip empty line
stdIn.nextLine();
userAnswer = stdIn.nextLine();
} while (userAnswer.equals("y"));
System.out.println("Goodbye!");
stdIn.close();
}
// Prompt user to provide the number of simulations and number of people and return them as an array
public static int[] promptAndRead(Scanner stdIn) {
int numberOfSimulations = 0;
while(numberOfSimulations < 1 || numberOfSimulations > 50000) {
System.out.println("Please Enter the number of simulations to do. (1 - 50000) ");
numberOfSimulations = stdIn.nextInt();
}
int sizeOfGroup = 0;
while(sizeOfGroup < 2 || sizeOfGroup > 365) {
System.out.println("Please Enter the size of the group of people. (2 - 365) ");
sizeOfGroup = stdIn.nextInt();
}
int[] simulationVariables = {numberOfSimulations, sizeOfGroup};
return simulationVariables;
}
// This is the method that actually does the calculations.
public static double compute(int numOfSims, int numOfPeeps) {
double numberOfSims = 0.0;
double simsWithCollisions = 0.0;
int matchingBirthdays = 0;
int[] birthdays = new int[numOfPeeps + 1];
int randomSeed = 0;
for(int i = 0; i < numOfSims; i++)
{
randomSeed++;
Random rnd = new Random(randomSeed);
birthdays = new int[numOfPeeps + 1];
matchingBirthdays = 0;
for(int j = 0; j < numOfPeeps; j++) {
birthdays[j] = rnd.nextInt(365);
Arrays.sort(birthdays);
}
for(int k = 0; k < numOfPeeps; k++) {
if(birthdays[k] == birthdays[k+1]) {
matchingBirthdays++;
}
}
if(matchingBirthdays > 0) {
simsWithCollisions = simsWithCollisions + 1;
}
}
numberOfSims = numOfSims;
double chance = (simsWithCollisions / numberOfSims);
return chance;
}
}
The line "birthdays[j] = rnd.nextInt(365);" seems to generate extra 0's in the int[] birthdays array.
Well, it doesn't. The array elements where zero to start with.
What that statement actually does is to generate a single random number (from 0 to 364) and assign it to one element of the array; i.e. the jth element. That is not what is required for your problem.
Now, we could fix your code for you, but that defeats the purpose of your homework. Instead I will give you a HINT:
The birthdays array is supposed to contain a COUNT of the number of people with a birthday on each day of the year. You have to COUNT them. One at a time.
Think about it ...
int arrays are by default initialized to 0 unless explicitly specified. Please see this Oracle tutorial about Arrays.
I found the problem myself. The issue was that having the "Arrays.sort(birthdays);" statement inside of a loop. That generated extra 0's.

Storing the input in 3 dimentional arrays

I want to store the input for different test cases that want to test with my java program .
below the sample input :
1
4 5
2 5 6 8
3 8 5 1 7
Here:
1st line- No of test cases.
2nd line-length of arrays M and N.
3rd line- elements of M array.
4th line: elements of N array .
My problem , how to store all these elements at run time and given them as input my java class .
As #Vamsi krishna suggested, the separate lines for the input are not really relevant. So you can enter the values as arguments to the java command line and read them in your main method:
public static void main(String[] args) {
int i = 0;
int numberOfTests = Integer.parseInt(args[i++]);
int mSize = Integer.parseInt(args[i++]);
int nSize = Integer.parseInt(args[i++]);
int[] mValues = new int[mSize];
for(n = 0; n < mSize; n++) {
mValues[n] = Integer.parseInt(args[i++]);
}
int[] nValues = new int[nSize];
for(n = 0; n < mSize; n++) {
nValues[n] = Integer.parseInt(args[i++]);
}
}
Then call your application with:
java MyApp.class 1 4 5 2 5 6 8 3 8 5 1 7
Note: you did not indicate how the number of test cases should be used. If this means multiple groups of m,n arrays can be specified as input an extra iteration is needed and the m,n arrays must be stored somewhere, for example in another array.
If this simple approach is not good enough (it might be too error prone because of the lack of formatting on the input) you could put the input in a file and read it using java.util.Scanner:
public static void main(String[] args) {
File file = new File(args[0]);
Scanner sc = new Scanner(file);
try {
while (sc.hasNextInt()) {
int i = sc.nextInt();
// see logic above but use sc.nextInt() to get the next int value
}
}
finally {
sc.close();
}
}
Call this with:
java MyApp.class C:\input.txt
And put the input in the file C:\input.txt.
/*
* Sharing the code here with . Yes,there will be multiple test cases in
* the input Suggest any better way if you find
*/
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int testcases = Integer.parseInt(br.readLine());
String readinput = "";
int count = 0;
int[][][] array = new int[testcases][3][];
for (int i = 0; i <= array.length; i++) {
readinput = "";
count = 0;
for (int j = 0; j < array[i].length; j++) {
readinput = br.readLine();
count = readinput.split(" ").length;
String[] data = new String[count];
data = readinput.split(" ");
System.out.println(Arrays.toString(data));
for (int k = 0; k < count; k++) {
array[i][j][k] = Integer.parseInt(data[k]);
}
}
}

loop is cut one element of the array

The problem is :
Write a program that reads a number n and then declares an array of n elements. The program then fills the array with the first n numbers, where each number is two to the power of the previous. Finally, display array’s contents.
My code :
import java.util.*;
public class Q1 {
static Scanner scan = new Scanner (System.in);
public static void main(String args [] ) {
int num;
int i = 0;
System.out.println("Enter a number :");
num = scan.nextInt();
double [] a=new double[num];
a[0]= num ;
for ( ;i<=a.length-1 ; i++) {
a[i+1] = Math.pow(2,a[i]);
System.out.println((int)(a[i]) );
}
}
}
The error is :
----jGRASP exec: java Q1
Enter a number :
4
4
16
65536
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at Q1.main(Q1.java:16)
----jGRASP wedge2: exit code for process is 1.
why it says that?
And the number by user printed twice!
a[i+1] = Math.pow(2,a[i]); // issue here
When i=a.length-1, i+1 is a.length. So there is no index value match in this array.
Suggestion:
Create an array witch has lenght= a.length+1
double powArray[] =new double[a.length+1];
Now
powArray[0]=a[0];
for(int i=1;i<powArray.length;i++){
powArray[i]=Math.pow(2,a[i-1]);
}
Issue is on line.16 as per compiler : a[i+1] = Math.pow(2,a[i]); The problem is indexes are not properly matched here.So it gives ArrayIndexOutOfBound Exception.Here i=a.length-1, i+1=a.length.So it is giving ArrayIndexOutOfBound Exception.
You should check that your index is not negative and not higher than the array length before accessing an array item.
Refer this : Avoiding index out of bounds exceptions
Concentrate on below portion of your code, its easy and you'll feel good if you figure out yourself:
for ( ;i<=a.length-1 ; i++) // check from where i starts and where it ends
{
a[i+1] = Math.pow(2,a[i]); // check what value of i would be here on each iteration
System.out.println((int)(a[i]) );
}
Also you could use a debugger and check every iteration
Few things to look upon here.
You have written a[0]= num ; which means the first value in the array is the same as the number entered by the user. Thus, you can see the number printed again. Thus,
a[0] = 1; // initial value has to be 1, contrary to what you've used
Next, your loop to generate the array values needs to be fixed. When you have i+1, the array index goes out of bounds in the last iteration, where your i is a.length - 1. Thus change your loop to something like this
for (int i = 1; i < a.length; i++) {
a[i] = Math.pow(2, a[i-1]);
}
Now, print the array values in a separate loop, as the previous loop won't print the value of the first index of the array.
for (int i = 0; i < a.length; i++) {
System.out.println((int)a[i]);
}
Change the upper limit to a.length-2 .Rest code remain same
import java.util.*;
public class Q1 {
static Scanner scan = new Scanner (System.in);
public static void main(String args [] ) {
int num;
int i = 0;
System.out.println("Enter a number :");
num = scan.nextInt();
double [] a=new double[num];
a[0]= num ;
for ( ;i<=a.length-2 ; i++) {
a[i+1] = Math.pow(2,a[i]);
System.out.println((int)(a[i]) );
}
}
}
int num ;
System.out.println("Enter a number :");
num = scan.nextInt();
double [] a=new double[num];
a[0]= num ; //Assign First Element To Array
double prev = a[0];
for(int i=1;i<a.length;i++){
a[i] = Math.pow(2,prev);
prev = a[i];
}
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
Output
Enter a number :
3
3.0
8.0
256.0
Just change the loop to :
for(;i < a.length-1;i++)
since when you assign 4 as a length for a[]..
you have a[0],a[1],a[2],a[3]... 4 slots.
Now a.length gives 4.
so for your a[i+1] for i=a.length-1 (i.e 3 ) .. a[i+1] = a[4]... which is out of the array bound for you array.
import java.util.*;
public class Q1 {
static Scanner scan = new Scanner (System.in);
public static void main(String args [] ) {
int num;
int i = 0;
System.out.println("Enter a number :");
num = scan.nextInt();
double [] a=new double[num];
for ( ;i<a.length ; i++) {
a[i] = Math.pow(2,i);
System.out.pri``nt((int)a[i]+ " ");
}
}
}

Categories

Resources