I'm trying to solve this Play With Numbers. I have passed the test cases but, I kept getting time limit exceeded. Can someone help me improve its performance in order to pass the time limit, please?
Problem:
You are given an array of n numbers and q queries. For each query you have to print the floor of the expected value(mean) of the subarray from L to R.
Input:
First line contains two integers N and Q denoting number of array elements and number of queries.
Next line contains N space seperated integers denoting array elements.
Next Q lines contain two integers L and R(indices of the array).
Output:
print a single integer denoting the answer.
Constraints:
1<= N ,Q,L,R <= 10^6
1<= Array elements <= 10^9
My code:
import java.io.*;
import java.util.*;
class TestClass
{
public static void main(String args[] ) throws IOException
{
Scanner sc=new Scanner(System.in);
int n= sc.nextInt();
int q= sc.nextInt();
int arr[]=new int[n];
int sums[]=new int[n+1];
sums[0]=0;
for(int i=0;i<n;i++)
{
arr[i]=sc.nextInt();
sums[i+1]=sums[i]+arr[i];
}
for(int i=0;i<q;i++)
{
int q1=sc.nextInt();
int q2=sc.nextInt();
int end=(q2-q1)+1;
int mean= (sums[q2]-sums[q1-1])/end;
System.out.println(mean);
}
}
}
According to my not-so-scientific tests, this doubles the speed:
sc.nextLine(); // to finish row #1
String line = sc.nextLine();
String[] parts = line.split(" ");
for (int i = 0; i < parts.length; i++) {
arr[i] = Integer.parseInt(parts[i]);
sums[i + 1] = sums[i] + arr[i];
}
As you see, the little trick is to minimize the number of reads that the Scanner has to to (as there normally is a bit of 'lag' surrounding each 'read'). I read from a file, not from System.in, so maybe you will not see the same improvement in your setup.
Related
I am trying to multiply two largest numbers from an array of numbers. Its working fine for small numbers.
Correct input / output - this is working:
3 10 2 8
80
Correct input / output - this is failing:
2 100000 90000
9000000000
My output is however 10000000000 instead.
Can someone tell me what is wrong in my code?
public static Long sumPairwise(Long[] numbers){
int index=0;
int n = numbers.length;
for(int i=1;i<n;i++){
if(numbers[i]>numbers[index])
index=i;
}
numbers[n-1]= numbers[index];
index=0;
for(int j=1;j<n-1;j++){
if(numbers[j]>numbers[index])
index=j;
}
numbers[n-2]=numbers[index];
Long product = (numbers[n-2])*(numbers[n-1]);
return product ;
}
public static void main(String [] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Long numbers[] = new Long[n];
for (int i=0;i<n;i++)
numbers[i]= sc.nextLong();
System.out.println(sumPairwise(numbers));
}
There is a bug in your code: numbers[n-1] may well contain the second highest number. You are overwriting that number with the highest number in your code, before you try and put it at the first to last position.
One way to overcome this is to sort the array using Arrays.sort, this way you are sure that the last two numbers are the highest and second highest number.
public static long multiplyLargestTwoNumbers(long[] numbers) {
long[] sortedNumbers = numbers.clone();
Arrays.sort(sortedNumbers);
int size = numbers.length;
// multiply highest and second highest number
return sortedNumbers[size - 1] * sortedNumbers[size - 2];
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
long numbers[] = new long[n];
for (int i = 0; i < n; i++) {
numbers[i] = sc.nextLong();
}
System.out.println(multiplyLargestTwoNumbers(numbers));
}
Other changes:
using long instead of Long: try and use primitive types when the objective reference types are not needed (you need Long if you want to use e.g. a List because a List can only hold object references);
spaced out for loops, please use white space;
renamed method, as it does't add anything pairwise;
used curly braces for for loop in main method;
removed spurious parentheses in part that performs multiplication.
You might also introduce an if statement that first checks if the numbers array does indeed contain at least two elements. This is called a guard statement.
Finally remember that byte, short and long all contain signed numbers of a specific bit size. Basically you are performing calculations modulus 2^n where n is the bit size. If the value is too large it may overflow and return an incorrect result. For that you need BigInteger.
You are replacing the original number in that index with another number.
That is causing the issue.
Please just simply find the max 2 numbers from below logic and multiply.
Also, remember to close scanner.
Here the simple solution. This will work only for positive integers.
import java.util.Scanner;
public class Snippet {
public static long multiplyHighestTwoValues(Long[] numbers) {
long maxOne = 0;
long maxTwo = 0;
for (long n : numbers) {
if (maxOne < n) {
maxTwo = maxOne;
maxOne = n;
} else if (maxTwo < n) {
maxTwo = n;
}
}
long product = maxOne * maxTwo;
return product;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Long numbers[] = new Long[n];
for (int i = 0; i < n; i++)
numbers[i] = sc.nextLong();
System.out.println(sumPairwise(numbers));
sc.close();
}
}
Instead of Long try to use BigInteger to multiply larger values that fit into long, otherwise your result may overflow.
Use BigDecimal instead for multiplying floating point numbers.
I have researched and tried for hours to solve my problem, but the reality is that I can't find anything on it. It is simple really. I need to initialize java arrays of undefined size, and then compare the two. In the process of testing my program, when I have defined the array to a specific length (for example)
int[] array = new int[6];
the code waits until I have entered the six objects to move on to the next segment of code, because it is waiting for 6 integers as defined as the array length. But I can't define the array using
int[] array = {};
it obviously won't work, since array.length function will be 0.
My code is below.
import java.util.Scanner;
import java.util.Arrays;
public class Test {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
// My problem is in the definition of the arrays or the for loops defining them below.
int[] list1 = new int[]; // undefined
int[] list2 = new int[]; // undefined
// ask user to fill the two arrays to see if they are equal
System.out.print("Enter list one >> ");
for (int i = 0; i < list1.length; i++){
list1[i] = input.nextInt();
}
System.out.print("Enter list two >> ");
for (int i = 0; i < list2.length; i++){
list2[i] = input.nextInt();
}
// call the equality testing method and output whether or not the two lists are strictly identical or not.
if (equals(list1, list2) == true)
System.out.println("The two lists are strictly identical");
else
System.out.println("The two lists are not strictly identical");
}
// this method
public static boolean equals(int[] list1, int[] list2){
boolean bool = false;
if (Arrays.equals(list1, list2))
bool = true;
else
bool = false;
return bool;
}
}
I need to initialize java arrays of undefined size,
You need to use an ArrayList or ask the length at the start.
List<Integer> list1 = new ArrayList<>();
System.out.println("Enter numbers, with a blank line to end");
for (String line; !(line = input.nextLine()).trim().isEmpty(); ) {
list1.add(Integer.parseInt(line));
}
// later
if (list1.equals(list2))
or use an array
System.out.println("Enter the number of numbers, followed by the numbers");
int[] array1 = new int[input.nextInt()]; // enter the size first.
for (int i = 0; i < array1.length; i++)
array[i] = input.nextInt();
// later
if (Arrays.equals(array1, array2))
int[] array = {};
it obviously won't work, since array.length function cannot work.
This works as expected and array.length is always 0
I am still unable to fulfill what I am really trying to accomplish, but I've used my code to compromise. It is to allow the user to specify the length before entering integers.
import java.util.Scanner;
import java.util.Arrays;
public class Test {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.print("How many variables long is the first list? ");
int n = input.nextInt();
int[] list1 = new int[n];
System.out.print("How many variables long is the second list? ");
n = input.nextInt();
int[] list2 = new int[n];
// ask user to fill the two arrays to see if they are equal
System.out.print("Enter list one >> ");
for (int i = 0; i < list1.length; i++){
list1[i] = input.nextInt();
}
System.out.print("Enter list two >> ");
for (int i = 0; i < list2.length; i++){
list2[i] = input.nextInt();
}
// call the equality testing method and output whether or not the two lists are strictly identical or not.
if (equals(list1, list2) == true)
System.out.println("The two lists are strictly identical");
else
System.out.println("The two lists are not strictly identical");
}
// this method
public static boolean equals(int[] list1, int[] list2){
boolean bool = false;
if (Arrays.equals(list1, list2))
bool = true;
else
bool = false;
return bool;
}
}
I see that this question is an older one but I had the same one (or at least similar) and couldn't find answer I was searching for. And now I believe I have the answer for this and would like to share it. Maybe for someone this will be handy.
According to my understanding the question is about creating a single dimensional array with undefined length and the length of this array is going to be increased by the Scanner input. Lot of answers I have seen were about using the ArrayList. But still I wanted to know how to do it with a single dimensional array. First, let me share with you the code and then the explanation:
public class Main {
static Scanner scanner = new Scanner(System.in);
final static int ARRAY_MAX_LENGTH = 400_000_000;
public static void main(String[] args) {
int[] numbers = createIntArray();
displayArray(numbers);
}
public static int[] createIntArray() {
int[] ints = new int[ARRAY_MAX_LENGTH];
System.out.print("Enter numbers: ");
for (int i = 0; i < ints.length; i++) {
ints[i] = scanner.nextInt();
if (ints[i] == 0) {
break;
}
} return ints;
}
public static void displayArray(int[] ints) {
for (int i = 0; i < ints.length; i++) {
System.out.print(ints[i] + " ");
if (ints[i] == 0) {
break;
}
}
}
}
Now the explanation:
We want undefined/infinite array length. The truth is: you can not have it. In programming everything has limit. The byte limit is between -128 to 127 the short limit is -32,768 to 32,767 and the int limit is between -2,147,483,648 to 2,147,483,647. So how do you create array with undefined length? Paradoxically: set the array length. And the length should be the maximum length an array can hold. And then create an exit point when you want the array to accept no more inputs from the Scanner class. I solved it by including in my code the if statement with a break keyword (if(input == 0) break;). Once I do not want to make any input with the Scanner class I just type '0' and press enter and the array does not accept any other input and the inputs made before the '0' is saved int the defined int[] numbers array.
Now coming back to the array max length... I found articles that the array max length is the int max length minus 8 (or something similar). This didn't work for me. I read some posts here on Stack Overflow that the array length depends on the JVM and on other factors I have not explored further. I thing the max array length depends on some settings too but I don't want to lie. This is why I set my array length to 400 000 000. When I set the length to 500 000 000 I got the error:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
If you want to use this code just figure out what is your max array length and use it.
For me this problem was interesting to think about but definitely I would not use it in big programs. It is not efficient at all. For newbies: if you have just learned the one dimensional array, be patient, ArrayList is coming in your later studies and it could make things easier.
I'm quite new to java.
I'm trying out some things for a project but I don't get why this does not work.
The goal here is to let the user input numbers separated by spaces and end with a letter. The program then needs to count the even and odd indexed numbers and output which sum is larger.
I already made this successfully when the amount of numbers given was a constant, but now I want to make it adapt to the user input.
Because I want to put the numbers in an array I need to know the length of this array. To get this I want to count the amount of numbers the user puts in so I can create the appropriate length array.
For some reason the while loop does not end and keeps running. How do I count the amount of numbers put in?
EDIT
I've added in.next(); in the first while loop so it is not stuck at the first input element. This brings me to a further problem however of having two while loops trying to loop through the same input. I have tried to create a second scanner and resetting the first one, but it does not get the second loop to start at the first element. Previous answers show that this is not possible, is there a way to put this in one while loop while still using arrays to store the values?
P.S. The input values should be able to be any positive or negative integer.
Here is my complete code:
import java.util.Scanner;
public class LargerArraySum {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int length = 0;
System.out.println("Enter your numbers seperated by spaces, end with a letter");
while(in.hasNextInt()) {
length++;
in.next();
}
System.out.println(length);
int arra[] = new int[length];
while(in.hasNextInt()) {
for(int i=0;i<length;i++) {
int x = in.nextInt();
arra[i] = x;
}
}
int evenSum = EvenArraySum(arra);
int oddSum = OddArraySum(arra);
if(evenSum<oddSum) {
System.out.println("The sum of the odd indexed elements is bigger");
} else if(oddSum<evenSum) {
System.out.println("The sum of the even indexed elements is bigger");
} else {
System.out.println("The sum of the odd and even indexed elements is equal");
}
}
public static int EvenArraySum(int[] a) {
int sum = 0;
for(int i=1;i<a.length;i+=2) {
sum += a[i];
}
System.out.println("The sum of the even indexed elements is: " + sum);
return sum;
}
public static int OddArraySum(int[] a) {
int sum = 0;
for(int i=0;i<a.length;i+=2) {
sum += a[i];
}
System.out.println("The sum of the odd indexed elements is: " + sum);
return sum;
}
}
add in.next(); in the loop. Actually you don't need array. You can sum even and odd indexed numbers while reading without saving them.
1) Your first while-loop does not work because the iterator is always checking for further numbers in from the same position.
Example:
Position 0 1 2 3 4 5
Value 1 3 5 7 9 0
At start the iterator points to position 0. If you call hasNextInt() it will check if position 1 is available, in this case it will be true. At this moment the interator still points to position 0. So you increase your length and do the same thing again, so you have an infinite loop.
To move the iterator to the next position you need to call nextInt().
2) You can't iterate over the same Scanner with a second while-loop in that way. If you would correct you first while-loop the iterator would point to position 5 (it reached the end of the scanner). So the check for hasNextInt() will be false and the second while-loop will not be entered.
3) The comments already mentioned it, you could use an ArrayList for this use case like so:
final ArrayList<Integer> input = new ArrayList<>();
while ( in.hasNextInt() ) {
input.add( in.nextInt() );
}
System.out.println( input.size() );
( or like kitxuli mentioned in his answer, dont even store the values, just count them in the first while-loop)
Your code has 2 major problems . The first and the second while loops lets take a look at your first loop .
while(in.hasNextInt()) {
length++;
}
your condition in.hasNextInt() made you insert input because no variable was initialized with in.nextInt but also returns either [true] or [false] so as long as its true it will add to the length variable without prompting you to insert a [new input] .so the code should look like.
Int length = 0;
int k ;
while(in.hasNextInt()) {
length++ ;
k = in.nextInt();
}
you insert the input into an initialized variable k for ex then prompt the user to further input into k after adding to [length] then the loop will check your condition without prompting user for input.
Lets look at your second while loop.
while(in.hasNextInt()) {
for(int i=0;i<length;i++) {
int x = in.nextInt();
arra[i] = x;
}
}
In in.NextInt() you are prompting the user to enter new input once again so you don't need int x.Not even the while loop .However you MUST declare a new scanner in this ex: I call it c .The code should look like this.
int [] a = new int [length];
Scanner c = new Scanner (System.in);
for(int i=0;i<length;i++) {
if (c.hasNextInt()){
a[i] = c.nextInt();
} else
break;
}
You must add the if statement because if you get an alphabet in the int array you will get an exception error .The array a[i] will not prompt the user.
Of course it isn't practical to make the user enter the values twice so a better code to implement without using ArrayList class which I think you may not know very well is by using an empty String .
NEW CODE :-
String g = "";
String j ="";
int y ;
int q=0;
int w = 0;
while (in.hasNextInt())
{
y = in.nextInt();
g =g+y+",";
q++;
}
int arra [] = new int [q];
for(int r =0;r<g.length();r++) {
if(g.charAt(r)==(',')){
arra[w]=Integer.parseInt(j);
System.out.println(arra[w]);
w++;
j="";
}else{
j=j+g.charAt(r);
}
}
Another even better code :-You just insert your numbers separated by spaces without a letter ,hit enter and the array is filled.
Scanner in = new Scanner (System.in);
String g = "";
String j ="";
int y ;
int q=0;
int i=0;
int w = 0;
System.out.println("inset your input separated by spaces");
g = in.nextLine();
while(i<g.length()){
if((g.charAt(i))==(' ')){
q++;
}
i++;
}
int a [] = new int [q+1];
for(int r =0;r<g.length();r++) {
if(g.charAt(r)==(' ')){
a[w]=Integer.parseInt(j);
System.out.println(a[w]);
w++;
j="";
}else{
j=j+g.charAt(r);
}
}
a[w]=Integer.parseInt(j);
System.out.println(a[w]);
You are given S a sequence of n integers S = s1, s2, ..., sn. Please, compute if
it is possible to split S into two parts : s1, s2, ..., si and si+1, si+2, ….., sn
(1 <= i < n) in such a way that the first part is strictly decreasing while the
second is strictly increasing one. First take n as input and then take n more
integers, output yes or no.
This is what i tried
import java.util.Scanner;
public class Sequence {
public static int c;
public static void main(String[] args) {
int n;
int count = 0;
Scanner s = new Scanner(System.in);
n = s.nextInt();
int a[] = new int [n];
for(int i = 0; i<n; i++) // loop for taking input
{
a[i] = s.nextInt();
}
for(int i = 0; i<n-2; i++) // loop for finding the minimum point
{
if(a[i]<a[i+2])
{ c = i; // associated minimum valued index to c
for( ; i<n-2; i++) /* loop for checking whether after that the array
{ is decreasing or not*/
if(a[i+1]<a[i+2])
{
count = count+1;
}
else
{
}
}
}
if(count == n-2-c)
{
System.out.println("YES");
}
else
{
System.out.println("NO");
}
}
}
This code is not passing 1 Test Case on Hackerrank.com please suggest some solution.
One good way to do that is by binary search:
You will have three variables : lowbound,middle,upperbound and
you start from the middle of your array and lowbounf=0,upperbound =n-1.
Next you will check with a linear passing of the array if s1,s2,...smiddle are strictly decreasing and smiddle,....,sn are strictly increasing .If yes then middle is your solution.
If s1,s2,...smiddle is not strictly decrasing and smiddle,....,sn is not strictly increasing you have no solution.
If s1,s2,...smiddle is not strictly decrasing and smiddle,....,sn is strictly increasing then uperbound=middle,middle=(upperbound+lowbound)/2 and try again.
If s1,s2,...smiddle is strictly decrasing and smiddle,....,sn is not strictly increasing then lowbound=middle,middle=(upperbound+lowbound)/2 and try again.
This until you find a solution ,or find that there is no solution or until lowbound=upperbound.
Example:
sequence: 7 8 5 1 2 3 4 5 6 7 8
middle=5 (the element 3),lowbound=0,upperbound=10, 7,8,5,4,1,2,3 is not strictly decreasing ,while 4,5,6,7,8 strictly increasing.
so: upperbound=5,middle=2 (the element array[middle]=2),7,8,5 are strictly decreasing ,1,2,3,4,5,6,7,8 are stricty increasing so the solution is middle = 2 .(Note middle=2 means that is the third element of array, the first is array[0] ,second is array[1] and third is array[2]=array[middle]=5 ).
The above solution is trying log n times (due to binary search) to linearly check the array (every linear check is O(n)) .So this solution is O(n log n).
import java.util.*;
public class Main {
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();int f=0;
int arr[]=new int[n];
for(int i=0;i<n;i++)
{
arr[i]=sc.nextInt();
}
int i=0;
for(i=0;i<n-1;i++)
{
if(arr[i]<arr[i+1])
{
break;
}
}
for(int j=i+1;j<n-1;j++)
if(arr[j]>arr[j+1])
f=1;
if(f==1)
System.out.println("false");
else
System.out.println("true");
}
}
Chandu's girlfriend loves arrays that are sorted in non-increasing order. Today is her birthday. Chandu wants to give her some sorted arrays on her birthday. But the shop has only unsorted arrays. So, Chandu bought T unsorted arrays and is trying to sort them. But, he doesn't have much time to sort the arrays manually as he is getting late for the birthday party. So, he asked you to write a program to sort the T arrays in non-increasing order. Help him, or his girlfriend will kill him.
Input:
First line contains an integer T, denoting the number of test cases.
First line of each test case contains an integer N, denoting the size of the array.
Second line contains N space separated integers, denoting the array elements Ai.
Output:
For each test case, print the sorted array in non-increasing order.
Constraints:
1 <= T <= 100
1 <= N <= 105
0 <= Ai <= 109
MYApproach
My first approach is to code the solution using simple approach.For this,I tried BubbleSort Algorithm.But in the last TestCase,I am not getting Expected Output.I Used bubble sort to sort the elements which compares adjacent element for every iteration of k in sort loop.Thus,The smallest element will go at the end
Can anyone guide me Why?
Below is the Code:
public static void main(String args[] ) throws Exception
{
Scanner sc=new Scanner(System.in);
int T=sc.nextInt();//Take the int Input from user
sc.nextLine(); //to move to nextLine after consuming token
int NoOfElements=sc.nextInt();
sc.nextLine();//to move to nextLine
int x[]=new int[NoOfElements];
for(int i=1;i<=T;i++)
{
for(int j=0;j<NoOfElements;j++)
{
x[j]=sc.nextInt();
}
sort(x);
}
}
public static void sort(int p[])
{
for(int k=0;k<p.length-1;k++)
{
//bubble sort
for(int i=0;i<p.length-k-1;i++)
{
if(p[i]<p[i+1])
{
//swap
int temp=p[i];
p[i]=p[i+1];
p[i+1]=temp;
}
}
}
for(int m=0;m<p.length;m++)
{
System.out.print(p[m]);
System.out.print(" ");
}
System.out.println();
}
}
Input
2
5
2 5 2 4 3
5
5 4 2 3 1
My Code's Output
5 4 3 2 2
5 5 4 3 2 //Why I am getting 5 here.I could not correct it.
Expected Correct Output
5 4 3 2 2
5 4 3 2 1
You are only reading the number of elements once. Not once per test case.
Below I have updated your code to read the NoOfElements once for each test case and allocate an array there as well.
public static void main(String args[]) throws Exception {
Scanner sc = new Scanner(System. in );
int T = sc.nextInt(); //Take the int Input from user
sc.nextLine(); //to move to nextLine after consuming token
for (int i = 1; i <= T; i++) {
int NoOfElements = sc.nextInt(); // THIS LINE MOVED INTO LOOP
sc.nextLine(); // THIS LINE MOVED INTO LOOP
int x[] = new int[NoOfElements];
for (int j = 0; j < NoOfElements; j++) {
x[j] = sc.nextInt();
}
sort(x);
}
}