Arranging sequence / Sequence Analysis - java

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");
}
}

Related

Play With Numbers Programming Challenge (finding mean value of subarray in java)

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.

How to multiply two long values in java

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.

Adding values to an array of undefined size

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.

Java cut the sticks

I am very new to Java and I was trying to solve this problem on Hackerrank:
Here's the task:
https://www.hackerrank.com/challenges/cut-the-sticks
You are given N sticks, where the length of each stick is a positive
integer. A cut operation is performed on the sticks such that all of
them are reduced by the length of the smallest stick.
Suppose we have six sticks of the following lengths:
5 4 4 2 2 8
Then, in one cut operation we make a cut of length 2 from each of the six
sticks. For the next cut operation four sticks are left (of non-zero length), > whose lengths are the following:
3 2 2 6
The above step is repeated until no sticks are left.
Given the length of N sticks, print the number of sticks that are left before > each subsequent cut operations.
Note: For each cut operation, you have to recalcuate the length of smallest
sticks (excluding zero-length sticks).
Here is my attempt at it, but it doesnt seem to be working. The output gets stuck in while loop (4 gets printed out infinitely)
import java.io.*;
import java.util.*;
public class Solution {
private static int findMin (int[] A)
{
int min = A[0];
for (int i =0; i<A.length; i++)
{
if (A[i] < min)
{
min = A[i];
}
}
return min;
}
private static int countNonZeros (int[] A)
{
int zeros = 0;
for (int i =0; i<A.length; i++)
{
if (A[i] == 0)
{
zeros++;
}
}
int nonZeros = A.length - zeros;
return nonZeros;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] A = new int[n];
for (int i=0; i<n; i++)
{
A[i] = scanner.nextInt();
}
int nums = countNonZeros(A);
while (nums > 0)
{
int mins = findMin(A);
for (int j = 0; j<A.length; j++)
{
A[j]=A[j]-mins;
}
nums = countNonZeros(A);
System.out.println(nums);
}
}
}
Any help is appreciated
(PS I know I can just look the solution up somewhere, but I want to know why my code isn't working)
The problem that you have is that your findMin is not excluding zero-length elements, so once you have a zero that will be the min, and as a result an iteration of the while loop will be the same as the previous iteration, having subtracted 0 from each of the elements of A.

Numbers I can get by adding an array in java

I need to get a minimum number that I cant get by adding different numbers of an array. Basically if I have these numbers:1,1,1,5; I can get 1,2,3,5,6... but I cant get 4 so that is the number I am looking for. Now this is my code:
import java.util.Scanner;
public class Broj_6 {
public static void main(String[] args) {
Scanner unos = new Scanner(System.in);
int k;
int n = unos.nextInt();
int niz []= new int [n];
for(int i = 0;i<n;i++){
niz[i]=unos.nextInt();
}
BubbleSort(niz);
for(int i = 0;i<n;i++){
System.out.print(niz[i] + " ");
}
for(int br = 1;br<=10000;br++){
for(k = 1;k<n;k++){
if(niz[k]>br){
break;
}
}
int podniz [] = new int [k];
for(int i=0;i<podniz.length;i++){
niz[i] = podniz[i];
}
//This is where I will need my logic to go
}
}
static void BubbleSort (int [] niz){
int pom;
for(int i = 0;i<niz.length-1;i++){
for(int j = 0;j<niz.length-1-i;j++){
if(niz[j]>niz[j+1]){
pom = niz[j];
niz[j] = niz[j+1];
niz[j+1] = pom;
}
}
}
}
}
So the code goes by testing each number individually from 1 to 100000 and makes a subarray of all numbers given that are less than the number itself. Now here is the problem,I dont know how to mix and match the numbers in the subarray so it can get(or not get) the desired number. When every combination is tested and there is no desired number,I will break; the loop and print i. Just to clarify,I can only use addition,and each number can only go in once
You can achieve this as below:
Use two nested loops, like below to calculate the sum of different numbers:
List<Integer> additionList = new ArrayList<Integer>();
int []inputNumbers = .... // Logic to read inputs
for(int _firstIndex = 0; _firstIndex < totalInputs; _firstIndex++){
for(int _secondIndex = _firstIndex + 1; _secondIndex < totalInputs; _secondIndex++){
additionList.add(inputNumbers[_firstIndex]); // only because you have 1 in the sample output
additionList.add(inputNumbers[_firstIndex] + inputNumbers[_secondIndex ]);
}
}
Then sort additionList and look for any missing entry. The first missing entry will be your answer,
Sorting the whole array and then finding sum of all subarrays does solve the problem, but is costly: O(2n^2) ~ O(n^2).
More efficient way to solve this will be Kadane's Algorithm: http://en.wikipedia.org/wiki/Maximum_subarray_problem
What the algo does:
Start from first element and increase the array size (sub array) till you reach the sum you're desiring.
my_num = 1;
while(true){
if(sum_subarray) > my_num){
current position = new subarray;
}
and this subarray concept is calculated through Kadane's approach:
def sum_subarray(A):
sum_ending_here = sum_so_far = 0
for x in A:
sum_ending_here = max(0, max_ending_here + x)
sum_so_far = max(sum_so_far, sum_ending_here)
return sum_so_far
I couldn't solve the problem completely. 'my_num' mentioned here needs to be incremented from 1, and break when my_num > max_sum. I hope someone can add to it and make it compilable.
Note:
This will also take care if negative elements are present in array.

Categories