Rotate Array by k - java

Given an array and a number k we have to rotate array k times.
Sample Input
1 //number of of testcases
5 2 //5(array size) 2(K value)
1 2 3 4 5 /array elements
Sample output
4 5 1 2 3
Here is my code
import java.util.*;
class TestClass {
public static void main(String args[] ) throws Exception {
// Write your code here
Scanner input=new Scanner(System.in);
int testcases=input.nextInt();
for(int i=0;i<testcases;i++)
{
int size=input.nextInt();
int rotationNo=input.nextInt();
rotateArray(size, rotationNo, input);
}
}
public static void rotateArray(int size, int rotationNo, Scanner input)
{
int[] arr=new int[size];
int[] result=new int[size];
rotationNo=rotationNo%size;
for(int i=0;i<size;i++)
{
arr[i]=input.nextInt();
}
int resultIndex=0;
int index=size-rotationNo;
int k=index,t=0,track=0;
while(true)
{
if(k<size)
{
System.out.print(arr[k++]+" ");
++track;
if(track==size)
{
break;
}
else
{
continue;
}
}
if(t<index)
{
if(t==(index-1))
{
System.out.print(arr[t++]);
}
else
{
System.out.print(arr[t++]+" ");
}
++track;
if(track==size)
{
break;
}
else
{
continue;
}
}
}
System.out.println();
}
}
This question was asked in a programming competition. My all testcases were passing except one which showed time limit exceeded. But I am not understanding what is the cause of time limit exceed. Loops will always halt whatever be the testcase.
Time Complexity of my code is O(n).
Is there another better and efficient solution?

Start outputting the input directly (i.e. without storing it) as soon as k values have been read and stored.
Then output the k initially read and stored values.
The shifting inside the array, is the relevant operation here.
The fewer shifts are done (the distance of shifting is not really relevant here, if implemented correctly), the better. It includes the storing and retrieving to/from an array. I consider the reading and outputting, if done without any processing in between, to be negligible. I.e. I focus on the shifting.
Strictly speaking, the reading and outputting is processing and that would mean that no improvement of O() can be calculated.
But allow me to ignore the reading and outputting for an O() estimation of the improvement:
The proposed recommendation will improve the number of array-accesses during shifting from O(n) to O(k). Admittedly the reading and outputting is ignored here. Storing and retrieving from an array and especially the shifting inside the array is avoided here and that is the O(k) part which is relevant here.
So the relevant operations are O(k), ignoring n-k values in O(1).
A test case like
1
10000 1
1 2 3 4 5 6 7 8 ...
will easily eliminate programs which after reading and before outputting, do O(4*10000), i.e. store all, read and write all for shifting and then read all for outputting. Compared to O(2*1) for only storing a single value and reading again for outputting at the end.
(Yes, I know clean O() analysis does not use factors, or any digits. You stil get the point, I hope. ;-)
Here is a code proposal (simplified to a single testcase):
import java.util.*;
public class Test {
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int testcases= input.nextInt(); //ignored, assuming 1
int size = input.nextInt();
int rotation = input.nextInt();
int i=0;
int[] newArr = new int[rotation%size]; //small array
// based on the nice idea by User-Upvotedon'tsayThanks
for(; i<rotation%size; i++)
{
newArr[i] = input.nextInt(); // few write accesses
}
for(; i<size; i++)
{
System.out.println( input.nextInt()); //many direct outpots
}
for(i=0; i<rotation%size; i++)
{
System.out.println(newArr[i]); // few outputs from array
}
return;
}
}
For an input of:
1
5 2
1 2 3 4 5
It gets you an output of:
3
4
5
1
2
Same output for a modulo-requiring input of:
1
5 7
1 2 3 4 5

I have provided a solution below which will directly output the scanner input up until the size of input has been met. It has a constant time o(n) for input, however it only touches each item once. and avoids the use of a while loop that may otherwise increase the multiplier of the iterations.
public class Test {
public static void main(String[] args) {
int rotation = new Scanner(System.in).nextInt();
int size = new Scanner(System.in).nextInt();
int[] values = rotate(rotation, size, new Scanner(System.in));
for(int i : values){
System.out.println(i);
}
}
public static int[] rotate(int rotation, int size, Scanner input){
int[] newArr = new int[size];
for(int i = 0; i<size; i++){
int newPosition = i + rotation;
newPosition = newPosition >= size ? newPosition - size : newPosition;
newArr[newPosition] = input.nextInt();
}
return newArr;
}
}

Related

Why am I getting Time Limit Exceeded (TLE) error when using ArrayList<String[]> instead of int[][]?

So I was trying to implement the Floyd-Warshal algorithm for shortest distance pairs. My first implementation of the algorithm lead to time limit exceeded while the second version using a 2d array was successful. Can anyone point out why is the TLE coming in the first implementation?
Note: 1000000 = infinity
Input:
The first line of input contains an integer T denoting the no of test cases. Then T test cases follow. The first line of each test case contains an integer V denoting the size of the adjacency matrix. The next V lines contain V space separated values of the matrix (graph). All input will be integer type.
Output:
For each test case output will be V*V space separated integers where the i-jth integer denote the shortest distance of ith vertex from jth vertex. For INT_MAX integers output INF.
Sample Input:
2
2
0 25
10000000 0
3
0 1 43
1 0 6
10000000 10000000 0
Sample Output:
0 25
INF 0
0 1 7
1 0 6
INF INF 0
Code approach 1 (giving TLE):
/*package whatever //do not write package name here */
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG {
public static int parseInt(String no){
if(no.equals("10000000") || no.equals("INF")){
return Integer.MAX_VALUE;
}
else
return Integer.parseInt(no);
}
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
StringBuffer sb = new StringBuffer();
int t = Integer.parseInt(sc.nextLine());
while(t-->0){
int n = Integer.parseInt(sc.nextLine());
ArrayList<String[]> adj = new ArrayList<>(n);
for(int i=0;i<n;++i){
String[] input = sc.nextLine().split(" ");
adj.add(input);
}
for(int k=0;k<n;++k){
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
int cur = parseInt(adj.get(i)[j]);
int iToK = parseInt(adj.get(i)[k]);
int kToJ = parseInt(adj.get(k)[j]);
int infinity = Integer.MAX_VALUE;
if(iToK!=infinity && kToJ!=infinity && cur>iToK+kToJ)
adj.get(i)[j] = Integer.toString(iToK+kToJ);
if(parseInt(adj.get(i)[j])==infinity)
adj.get(i)[j]="INF";
}
}
}
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
sb.append(adj.get(i)[j]+" ");
}
sb.append("\n");
}
}
sc.close();
System.out.println(sb);
}
}
Second Approach (passed all test cases successfully):
/*package whatever //do not write package name here */
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG {
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
StringBuffer sb = new StringBuffer();
int t = sc.nextInt();
while(t-->0){
int n = sc.nextInt();
int[][] adj = new int[n][n];
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
adj[i][j] = sc.nextInt();
for(int k=0;k<n;++k){
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
adj[i][j] = Math.min(adj[i][j],adj[i][k]+adj[k][j]);
}
}
}
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
if(adj[i][j]==10000000)
sb.append("INF"+" ");
else
sb.append(adj[i][j]+" ");
}
sb.append("\n");
}
}
sc.close();
System.out.println(sb);
}
}
In short, each iteration of the first solution is much slower than each iteration of the second one. At each iteration, you do the following:
Integer.parseInt, which is pretty slow. You can check this answer: https://stackoverflow.com/a/22783022/12463032, to see that each parse takes about 60 ns, which is probably more than 10 times slower than all other operations in the loop. It should make sense: at the very least parseInt takes time linear on the length of the string. Moreover, the function is not trivial (at the very least, parseInt must check that the number is an integer).
Integer.toString, which again takes time linear of the length of the string. Moreover, it involves object (string) creation, and your time may increase because of memory processing (e.g. GC may not work that well in your settings, and don't forget about memory allocation).
On a higher level, you violate Item 50 from "Effective Java" (http://wavelino.coffeecup.com/pdf/EffectiveJava.pdf): Avoid strings when other types are more appropriate. You perform numerical computations on your data; therefore, you should store them as numbers.

How to manipulate the array in Java?

Starting with a 1-indexed array of zeros and a list of operations, for each operation, I have to add value to each of the array elements between two given indices, inclusive. Once all operations have been performed, I have to return the maximum value in the array. But the wrong answer is coming every time for most test cases and for some test cases time limit is exceeding. Kindly help me to solve this problem.
I am using arrayManipulation function to get the number of array elements and queries array. And update function is used to update(add the element) the array.
import java.util.*;
import java.util.Arrays;
public class sample
{
public static void main(String args[])
{
int maximum=0;
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int m=sc.nextInt();
int queries[][]=new int[m][3];
for(int x=0;x<m;x++)
{
for(int y=0;y<3;y++)
{
queries[x][y]=sc.nextInt();
}
}
maximum=arrayManipulation(n,queries);
System.out.println(maximum);
}
public static int arrayManipulation(int num,int qry[][])
{
int a=0,b=0,k=0;
int max=Integer.MIN_VALUE;
int arr[]=new int[num];
int arr2[]=new int[num];
for(int i=0;i<num;i++)
{
arr[i]=0;
}
for(int j=0;j<qry.length;j++)
{
for(int kl=0;kl<qry[0].length;kl++)
{
a=qry[j][kl];
b=qry[j][kl+1];
k=qry[j][kl+2];
break;
}
arr2=update(a,b,k,arr);
int lengtharr2=arr2.length;
max=Math.max(max,arr2[lengtharr2-1]);
}
return max;
}
public static int[] update(int a1,int b1, int k1,int array[])
{
for(int i=a1;i<b1;i++)
{
array[i]+=k1;
}
Arrays.sort(array);
return array;
}
}
Input: 10 means the number of array elements and 3 is no. of queries which consist of a,b,k values which mean like this: the left index, right index, and summand
10 3
1 5 3
4 8 7
6 9 1
My output:
11
expected output:
10
In this for loop:
for(int kl=0;k<qry[0].length;k++)
{
a=qry[j][kl];
b=qry[j][kl+1];
k=qry[j][kl+2];
break;
}
Why are you using two different variables (k and kl) in your loop condition?
Regardless, you should use a variable other thank k for the loop, as you are updating the value of k and then executing k++ at each iteration of your loop, which is very likely to mess up your output.
Consider something like:
for(int l=0;l<qry[0].length;l++)
{
a=qry[j][kl];
b=qry[j][kl+1];
k=qry[j][kl+2];
break;
}

What part of my code does not pass the Simple Array Sum tests of Hackerrank?

I am doing the Hackerrank questions to get better at solving puzzles. I've been working on the Simple Sum Array question in the Data Structures section for nearly 2 hours O_O
I seriously thought I solved it because I tested it on the terminal on my mac and it ran fine, but when I submit the code in Hackerrank, it failed all 3 test cases T_T
I don't understand where the problem is and why the test cases failed. Does anyone see the problem? Please help.
Below is the code:
import java.io.*;
import java.util.*;
public class Solution {
public static int sumArray( int[] arr ){ //arr stands for the array to pass in
int result = 0;
for (int i = 0; i < arr.length; i++){
result = result + arr[i];
}
return result;
}
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
Scanner input = new Scanner(System.in);
System.out.println("Print out the size of the array: ");
int size = input.nextInt();
int[] array = new int[size];
System.out.println("Type out the numbers you want in the array. One line only, each number is separated by a space");
String numbers = null;
String[] splitString = null;
while ( input.hasNextLine() ){
numbers = input.nextLine();
splitString = numbers.split("\\s");
if (splitString.length == size){
break;
}
}
//splitString = numbers.split("\\s");
int i = 0;
for (String s : splitString){
//System.out.println(s);
array[i] = Integer.parseInt(s);
i++;
}
System.out.println( sumArray(array) );
}
}
Also, here's the Hackerrank question to clarify what they wants:
Given an array of integers, can you find the sum of its elements?
Input Format:
The first line contains an integer, denoting the size of the array.
The second line contains space-separated integers representing the array's elements.
Output Format:
Print the sum of the array's elements as a single integer.
Sample Input:
6
1 2 3 4 10 11
Sample Output:
31
From the first time seeing your code you have two issues:
1- arr.length should be arr.length - 1
Because, your iteration starts from 0 and length not
2- the way you print your array is wrong
Because, you should use something like this:
Arrays.toString(array)

Java Online Judge Solution error

I'm trying to solve problem #299 - Train Swapping in website UVa Online judge. The code I have works fine for independent test cases. However, when I use the sample input they provide, my program omits one of the test cases, the last one to be more specific:
Here is my code:
import java.util.Scanner;
public class Tester {
void problem(){
Scanner imput = new Scanner(System.in);
int numT =imput.nextInt();
int numL, aux, swaps=0;
int [] train = new int [50];
for (int i =0; i<numT; i++) {
numL = imput.nextInt();
for (int m =0; m< numL; m++) {
train[m]=imput.nextInt();
}
for (int j=0; j<numL; j++) {
if (train[j]>train[j+1]) {
for (int k =j; k<numL-1;k++) {
aux = train[k];
train[k]=train[k+1];
train[k+1]=aux;
swaps++;
}
}
}
System.out.println("Optimal train swapping takes "+swaps+" swaps.");
swaps = 0;
}
}
}
Example Input:
3
3
1 3 2
4
4 3 2 1
2
2 1
Example Output:
Optimal train swapping takes 1 swaps.
Optimal train swapping takes 6 swaps.
Optimal train swapping takes 1 swaps.
My code prints until the second solution, then for some reason stops. I've tried to debug it and check what's going on step by step but it has driven me to a migraine point. Any insight is highly appreciated.
...
To be more precise it stops at the second for loop the third time around without taking anything into the array...and I don't know why!
Another thing I found out is that to solve this problem the number of swaps for the case of the middle is 6, therefore the bubble sort wont be useful here, since it makes over 10 swaps thus yielding a wrong output, this is a separate issue to the original one I presented however. I still haven't figure out why it stops the third time around the loop where I assign values to the array for the third time.
Rearrange your loop like follows:
for(int j=0; j<numL; j++){
for(int k =j+1; k<numL;k++){
if(train[j]>train[k]){
aux = train[j];
train[j]=train[k];
train[k]=aux;
swaps++;
}
}
}
Edited: for performance.
You can minimize a for loop, if you organize your code like below:
public class Main {
static int sum=0;
public static void sort(String[] str){
for(int i = 1; i < str.length; i++)
if(Integer.parseInt(str[i])<Integer.parseInt(str[i-1])){
String h = str[i];
str[i] = str[i-1];
str[i-1] = h;
sum++;
sort(str);
}
}
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(in.readLine().trim());
for (int i = 0; i < n; i++) {
sum = 0;
int x = Integer.parseInt(in.readLine().trim());
String s[] = in.readLine().trim().split(" +");
sort(s);
System.out.println("Optimal train swapping takes " + sum + " swaps.");
}
}
}

Method return Java assignment

Okay here's a Java assignment I've been having trouble with. I asked earlier about this and got some good comments and advice, but have since understood the assignment more clearly and the issue has changed a bit. So here's the assignment:
***
Your task is to complete the program below by writing three methods (askInfo, copyInfo and setArray). Program should ask for integers (max 100 integers) until the users types in zero. Integers can vary from one to one hundred and they are stored in an array that has 100 elements. Numbers are asked for with the askInfo method, which receives the array with numbers as parameter. Method returns the number of integers. The number zero is not saved in the array; it is merely used to stop giving input. The given numbers are then copied to another array which size is the amount of given numbers. Copying is done with copyInfo method which receives both arrays as parameters. After this the elements of the new array are put in ascending order with setArray method and printed on screen with printArray method.
Program to complete:
import java.util.*;
public class RevisionExercise {
public static void main(String[] args) {
int[] tempArray = new int[100];
System.out.println("Type in numbers. Type zero to quit.");
int amountOfNumbers = askInfo(tempArray);
int[] realArray = new int[amountOfNumbers];
copyInfo(realArray, tempArray);
setArray(realArray);
printArray(realArray);
}
// Your code here
public static void printArray(int[] realArray ) {
System.out.println("\Ordered array: ");
for(int i = 0; i < realArray .length; i++) {
System.out.println(realArray [i]);
}
}
Example print:
Type in numbers. Type zero to quit.
1. number: 3
2. number: 8
3. number: 5
4. number: 6
5. number: 9
6. number: 0
Ordered array:
9
8
6
5
3
I'm struggling with the askInfo method. So far I've written this but it returns only zeroes. Here's my askInfo method:
public static int askInfo(int[] tempArray) { //askinfo-metodi
Scanner reader = new Scanner(System.in);
int i;
for (i = 0; i < tempArray.length; i++) {
System.out.print((i+1) + ". number: ");
tempArray[i] = reader.nextInt();
if (tempArray[i] == 0) {
return tempArray[i];
}
}
return tempArray[i];
}
***
How can I make it to register the input and get the amount of numbers to be passed to the next method in the assignment as described in the assignment.
You never store your integer luku values in your array, so your array never changes from the default initialized integer values of all zeroes. Inside your loop, you need to add an
tempA[i] = luku;
After the if-statement confirms that luku is not 0. All in all:
if (luku == 0) {
return i;
}
tempA[i] = luku;

Categories

Resources