I am trying to recursively find the largest element in an array. The user has to input the number of elements that the array will have. My error is that if that the list does not have an element which is larger than the number of elements in the list, the output of the largest number will be the number of elements in the list. eg: array of 5 integers containing {1 1 1 2 3}. the answer will be 5 and not 3.
import java.util.*;
public class test7 {
public static int findLargest(int[] a, int max) {
int i=0, j=0, tempmax=0;
if (a.length == 1) return a[0]>max ? a[0]:max;
else if(max < a[i]){
max = a[i];
int[] tempArr = new int[a.length -1];
for (i=1; i<a.length; i++){
tempArr[j] = a[i];
j++;
}
tempmax = findLargest(tempArr, max);
return tempmax;
}
else{
int[] tempArr = new int[a.length -1];
for (i=1; i<a.length; i++){
tempArr[j] = a[i];
j++;
}
tempmax = findLargest(tempArr, max);
return tempmax;
}
}
public static void main(String[] args) {
int[] values = new int[100];
Scanner scan = new Scanner(System.in);
System.out.println("Enter the number of elements in your list: ");
int x = scan.nextInt();
if(x>1 || x<100){
for (int i=0; i<=(x-1); i++){
System.out.print("Enter your number: ");
System.out.println();
values[i] = scan.nextInt();
}
System.out.println();
System.out.println("The largest number is: "+findLargest(values, x));
}
else System.out.println("The maximum number of elements must be less than 100");
}
}
You call your method with:
System.out.println("The largest number is: "+findLargest(values, x))
This tells it to assume the largest number is x and try to find anything in the list that is greater than that. Of course, this produces the exact problem you described.
In general, when finding a maximum number, you want to initialize your candidate to the lowest number possible, or to the first number in your array.
If you initialize to the lowest number possible (Integer.MIN_VALUE) then as soon as you start your algorithm, the first number will definitely be bigger than it and will be chosen as the next candidate for maximum.
If you initialize to the first item in your array, then if that number is the highest, all well and good. If it is not, then when you encounter the next higher number, it will become the candidate, and all is good.
Which one you choose is up to you (and depends also on whether an empty array is possible), but the thing to remember is never to select an initial candidate that might be greater than all the elements in the array.
Try this working example:
public static void main(String[] args)
{
int[] numbers = {2, 5134, 333, 123, 8466};
int largest = numbers[0];
for(int i = 1;i<numbers.length;i++)
{
largest = Math.max(largest, numbers[i]);
}
System.out.println("Largest number: "+largest);
}
As a method that would look like this:
public static int max(int first, int... more)
{
for(int element:more)
{
first = Math.max(first, element);
}
return first;
}
You can then call it using something like max(1,23,564,234,543);
Related
You are given two arrays A and B each containing n, integers. You need to choose exactly one number from A and exactly one number from B such that the index of the two chosen numbers is not same and the sum of the 2 chosen values is minimum.
Your objective is to find and print this minimum value.
For example in the image shown below is the minimum sum.
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
static int twinArrays(int[] ar1, int[] ar2){
// Complete this function
int minAr1 = ar1[0];
int minAr2;
int index = 0;
for(int i =0; i<ar1.length;i++) {
if(ar1[i]<minAr1) {
minAr1 = ar1[i];
index = i;
}
}
if(index == 0) {
minAr2 = ar2[1];
}else {
minAr2 =ar2[0];
}
for(int j=0;j<ar2.length;j++) {
if(j!=index && minAr2>ar2[j]) {
minAr2 =ar2[j];
}
}
return minAr1+minAr2;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
if(n>=2 && n<=1000000) {
int[] ar1 = new int[n];
for(int ar1_i = 0; ar1_i < n; ar1_i++){
int temp1 = in.nextInt();
if(temp1>=1&&temp1<=1000000) {
ar1[ar1_i] = temp1;
}
}
int[] ar2 = new int[n];
for(int ar2_i = 0; ar2_i < n; ar2_i++){
int temp2 = in.nextInt();
if(temp2>=1&&temp2<=1000000) {
ar2[ar2_i] = temp2;
}
}
int result = twinArrays(ar1, ar2);
System.out.println(result);
}
}
}
i have Implemented that is working fine but still something is missing so some test case failing could anyone give me some clue and hint to optimize my code if you find any defect in this code
Your code works by finding the minimum value from the first array, then finding the minimum value from the second array that isn't at the same position of the minimum in the first array. The problem with this approach is that it isn't guaranteed to find the overall minimum sum. For example, consider these small arrays:
[0, 1], [0, 100]
Here, if you take the minimum value of the first array (0) and the minimum value of the second array that isn't at the same position (100), you get the sum 100. However, the correct sum to pick is the smallest value from the second array (0) and the second-smallest value from the first array (1) for a total of 1.
One observation that's useful here is that the minimum-sum pair must be one of the following:
The sum of the smallest values from each array.
The sum of the smallest value from one array and the second-smallest value from the other.
Your solution is on the right track here, except you don't consider taking the smallest from the second array and the second smallest from the first. Try editing your code to account for that case.
One simple observation is that if minimum elements from both arrays are at different position, Sum of both elements would be an answer so after sorting answer in this case would be A[0]+B[0], but if both are at the same position, there are two possibilities for answer after sorting both the arrays.
Suppose we have two arrays A and B which are sorted in increasing order. Then there are two possible answers and the actual answer would be minimum of them.
Take minimum possible number from array A so that number would be A[0] and now find the minimum possible number from array B such that index of that element is not equal to 0 so best possible choice would be B[1]. Therefore answer in this case is A[0]+B[1].
Another possibility is that we consider minimum possible number from array B first and then go to choose a number from array A so here those numbers would be A[1] and B[0] respectively and thus answer in this case is A[1]+B[0].
Now for the final answer, we can take minimum of both these possible answers.
Final_Answer = min(A[0]+B[1],A[1]+B[0]);
If you don't want to sort the Arrays due to tight time constraint. You can just keep track of First and Second minimum element of both arrays and use it in place of A[0],A[1] in above equation respectively.
A sample code using first and second minimum,
static int twinArrays(int[] ar1, int[] ar2){
int first_minimum_ar1 = Integer.MAX_VALUE;
int second_minimum_ar1 = Integer.MAX_VALUE;
int index_ar1=-1;
int first_minimum_ar2 = Integer.MAX_VALUE;
int second_minimum_ar2 = Integer.MAX_VALUE;
int index_ar2=-1;
for(int i=0;i<ar1.length;i++)
{
int element = ar1[i];
if(first_minimum_ar1>=element)
{
second_minimum_ar1=first_minimum_ar1;
first_minimum_ar1=element;
index_ar1=i;
}
else if(second_minimum_ar1>element)
{
second_minimum_ar1=element;
}
}
for(int i=0;i<ar2.length;i++)
{
int element = ar2[i];
if(first_minimum_ar2>=element)
{
second_minimum_ar2=first_minimum_ar2;
first_minimum_ar2=element;
index_ar2=i;
}
else if(second_minimum_ar2>element)
{
second_minimum_ar2=element;
}
}
if(index_ar2!=index_ar1)
return first_minimum_ar1+first_minimum_ar2;
return Math.min(first_minimum_ar1+second_minimum_ar2,first_minimum_ar2+second_minimum_ar1);
}
What I did was, sort one array(ar1) in ascending order(take ar[0]) and the other in descending order(ar2) and then take (ar2[ar2.length-1]).
class TwinArray{
static int twinArrays(int[] ar1, int[] ar2){
Arrays.sort(ar1);
Integer[] Ar2 = new Integer[ar2.length];
for (int i=0;i<ar2.length;i++)
Ar2[i]=ar2[i];
Arrays.sort(Ar2,Collections.reverseOrder());
System.out.println(Ar2[Ar2.length-1]);
return (ar1[0]+Ar2[Ar2.length-1]);
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] ar1 = new int[n];
for(int ar1_i = 0; ar1_i < n; ar1_i++){
ar1[ar1_i] = in.nextInt();
}
int[] ar2 = new int[n];
for(int ar2_i = 0; ar2_i < n; ar2_i++){
ar2[ar2_i] = in.nextInt();
}
int result = twinArrays(ar1, ar2);
System.out.println(result);
}
}
This one will probably pass all of your test cases.
Runtime Complexity ~ o(n)
static int twinArrays(int[] ar1, int[] ar2){
int ar1Minimum = Integer.MAX_VALUE , ar1MinIndex = -1;
int ar1SecondMin = Integer.MAX_VALUE ;
//Get the element with minimum value and index
for(int i = 0 ; i < ar1.length ; ++i){
if(ar1Minimum > ar1[i]){
ar1Minimum = ar1[i]; ar1MinIndex = i;
}
}
//Get the second minimum
for(int i = 0 ; i < ar1.length ; ++i){
if(ar1SecondMin > ar1[i] && i!=ar1MinIndex){ // i != ar1MinIndex = Important to avoid duplicate minimum values [1,1,2,4] min = 1 , secondMin = 2 and not 1
ar1SecondMin = ar1[i];
}
}
int ar2Minimum = Integer.MAX_VALUE , ar2MinIndex = -1;
int ar2SecondMin = Integer.MAX_VALUE ;
for(int i = 0 ; i < ar2.length ; ++i){
if(ar2Minimum > ar2[i]){
ar2Minimum = ar2[i]; ar2MinIndex = i;
}
}
for(int i = 0 ; i < ar2.length ; ++i){
if(ar2SecondMin > ar2[i] && i != ar2MinIndex){
ar2SecondMin = ar2[i];
}
}
if(ar1MinIndex != ar2MinIndex){
return ar1Minimum + ar2Minimum;
}
return Math.max((ar1Minimum + ar2SecondMin), (ar1SecondMin + ar2Minimum));
}
I am creating a program that asks the user for ten numbers, then outputs the smallest and largest number. This is my code:
import java.util.Scanner; // program uses Scanner
public class ArrayTester {
// begin execution
public static void main(String[] args) {
// declare and create array object
// declare smallest and largest int variables
int[] numbers;
numbers = new int[10];
int smallest = numbers[0], largest = numbers[0];
// create Scanner object
Scanner input = new Scanner(System.in);
// prompt user
System.out.print("Please enter 10 numbers: \n");
// use for loop to obtain user input
for (int counter = 0; counter < numbers.length; counter++) {
numbers[counter] = input.nextInt();
} // end obtaining input
// enhanced for loop to find largest and smallest values
for (int i : numbers) {
if (i < smallest) {
smallest = i;
} // end finding smallest
else if (i > largest) {
largest = i;
} // end finding largest number
} // end finding largest and smallest values
// for loop to print user input
System.out.printf("%s%8s\n", "Index", "Input");
for (int counter = 0; counter < numbers.length; counter++) {
System.out.printf("%5d%8d\n", counter, numbers[counter]);
} // end printing input values
// print smallest and largest numbers
System.out.printf("Smallest number: %d\nLargest number: %d\n", smallest, largest);
} // end main
} // end ArrayTester
The problem I am having is when the numbers output, it's giving me 0 as the smallest and 9 as the largest. I know this is because of the 10 number array but how would it be fixed to show the smallest integer and largest integer?
numbers = new int[10];
The above statement initialises the array with all 0s, since you are assigning numbers[0] to smallest, it will always be 0.
Also, another way of achieveing this would be by using Java 8's stream, e.g.:
int[] array = new int[] {1,2,3,10,0};
IntSummaryStatistics summaryStatistics = Arrays.stream(array).summaryStatistics();
System.out.println(summaryStatistics.getMax());
System.out.println(summaryStatistics.getMin());
Put this line:
int smallest = numbers[0], largest = numbers[0];
Below this line:
for (int counter = 0; counter < numbers.length; counter++) {
numbers[counter] = input.nextInt();
} // end obtaining input
You're initializing "smallest" to 0, because your array doesn't have any values yet. Unless the user puts in a negative number, smallest will always be zero.
Whenever I am trying to run this code, it gives me out of bound exception. Can anyone point me out what's wrong with it.
package com.programs.interview;
import java.util.Scanner;
public class FindMaxNumInArray {
public static void main (String[] args)
{
Scanner scan = new Scanner (System.in);
System.out.print("Enter the size of the array: ");
int arraySize = scan.nextInt();
int[] myArray = new int[arraySize];
System.out.print("Enter the " + arraySize + " values of the array: ");
for (int i = 0; i < arraySize; i++)
myArray[i] = scan.nextInt();
for (int j = 0; j < arraySize; j++)
System.out.println(myArray[j]);
System.out.println("In the array entered, the larget value is "+ maximum(myArray,arraySize) + ".");
}
public static int maximum(int[] arr, int Arraylength){
int tmp;
if (Arraylength == 0)
return arr[Arraylength];
tmp = maximum(arr, Arraylength -1);
if (arr[Arraylength] > tmp)
return arr[Arraylength];
return tmp;
}
}
Output
Enter the size of the array: 5 Enter the 5 values of the array: 1 2 3
4 5 1 2 3 4 5 Exception in thread "main"
java.lang.ArrayIndexOutOfBoundsException: 5 at
com.programs.interview.FindMaxNumInArray.maximum(FindMaxNumInArray.java:26)
at
com.programs.interview.FindMaxNumInArray.main(FindMaxNumInArray.java:17)
This is the problem:
if (arr[Arraylength] > tmp)
Valid array indexes go from 0 to length-1 inclusive. array[array.length] is always invalid, and on the initial call, ArrayLength is equal to arr.length.
It's not clear why you're using recursion at all, to be honest. An iterative solution would be much simpler - but you'll need to work out what you want to do if the array is empty.
EDIT: If you really want how I would write the recursive form, it would be something like this:
/** Returns the maximum value in the array. */
private static int maximum(int[] array) {
if (array.length == 0) {
// You need to decide what to do here... throw an exception,
// return some constant, whatever.
}
// Okay, so the length will definitely be at least 1...
return maximumRecursive(array, array.length);
}
/** Returns the maximum value in array in the range [0, upperBoundExclusive) */
private static int maximumRecursive(int[] array, int upperBoundExclusive) {
// We know that upperBoundExclusive cannot be lower than 1, due to the
// way that this is called. You could add a precondition if you really
// wanted.
if (upperBoundExclusive == 1) {
return array[0];
}
int earlierMax = maximumRecursive(array, upperBoundExclusive - 1);
int topValue = array[upperBoundExclusive - 1];
return Math.max(topValue, earlierMax);
// Or if you don't want to use Math.max
// return earlierMax > topValue ? earlierMax : topValue;
}
you can't access
arr[Arraylength]
the last element would be at
arr[Arraylength -1]
for example if you have
int arr[] = new int[5];
then the elements would be at 4, because index starts from 0
arr[0], arr[1], arr[2], arr[3], arr[4]
Your issue is in the following piece of code:
if (arr[Arraylength] > tmp)
return arr[Arraylength];
Indexes start at 0, so you will be out of bound for an array with 5 elements [1,2,3,4,5] indexes: [0,1,2,3,4].
I would use a plain loop. Java doesn't do recursion particularly well.
public static int maximum(int[] arr) {
int max = Integer.MIN_VALUE;
for(int i : arr) if (i > max) max = i;
return max;
}
here
System.out.println("In the array entered, the larget value is "+ maximum(myArray,arraySize) + ".");
you are passing the arraysize where in maximum method you are returning arr[Arraylength] which giving ArrayIndexOutOfBound so change either in calling maximum(yArray,arraySize-1) or return arr[Arraylength-1] statement.
I'm new to java programming and i just cant figure out how to find the average of an array nor do i know how to print the array backwards. This is my code so far:
public static void forwards(int nums, int arrayNums[]){
for(int a=0;a<arrayNums.length;a++){
nums =(int)(Math.random()*90+10);
System.out.print(nums+" ");
}
System.out.println();
System.out.println();
//Average of the array
int average=0;
for(int b=0;b<arrayNums.length; b++){
average=(average+arrayNums[b]);
}
System.out.println();
System.out.println(average);
}
public static void backwards(int nums, int[] arrayNums){
//backwards of the array
for(int a=arrayNums.length; a>0;a--){
System.out.print(nums+" ");
}
}
public static void main (String [] args){
int[] arrayNums = new int [Integer.parseInt
(JOptionPane.showInputDialog("How many numbers do you want to input?"))];
int nums = 1;
forwards(nums,arrayNums);
System.out.println();
backwards(nums,arrayNums);
For average ---->
for (int i = 0; i < array.length; i++)
{
sum += array[i];
}
int avegare = sum / array.length;
For Backwards ---->
for(int i = Array.length - 1; i >= 0;i--)
Backwards should start with arrayNums.length-1:
public static void backwards(int nums, int[] arrayNums){
//backwards of the array
for(int a=arrayNums.length-1; a >= 0; a--){
System.out.print(arrayNums[a]+" ");
}
}
The reason is that indices go from 0 to array.length-1. That's basically what happens in a for loop.
For the average, you forgot a division by the number of elements...
"i just cant figure out how to find the average of an array nor do i know how to print the array backwards."
For averages, you should use a different method, instead of trying to it in the forwards method
public static double average(int[] arrayNums) {
double sum = 0;
...
double average = // how do you get the average of something?
return average;
}
I started you off with the basic outline. You basically need to add all the numbers to the sum, by looping through the array, then get the average by diving it by the total of numbers in the array. Then you can print out the average like
double average = average(array);
System.out.println(average)
for backwards, you want to print arrayNums[a] instead of nums. You should also start the loop from arrayNum.length - 1 as there is no index in the array arrayNums.length so you would get an ArerayOutOfBounds exception. Also you want the 0th index, so you want to use >=
for(int a = arrayNums.length - 1; a >= 0 ;a--) {
// print arrayNums[a]
You seem to be doing the same wrong thing for forwards as you are in backwards. You want to print the arrays value for each index a, and not nums
I would also create the random array in a different method
public static int[] randomArray(int num) {
int[] random = new int[nums];
.... may array by looping
return random;
}
Then you the main you could just do
int[] array = randomArray(num);
forwards(array);
backwards(array);
double average = average(array);
System.out.println(average);
As you can see, I pass no nums to the methods. I think you should take tha parameter out of the method signatures. I see no use for them.
Here is a simple way to find the average. Just add up each of the elements, and then divide by the total number of elements in the array:
public static double average(int[] array)
{
int average =0;
for(int i =0; i< array.length; i++ )
{
average += array[i];
}
return average/array.length;
}
Here is a backwards method. Start at array.length-1, which is the last index. From there, iterate down i--, and then end when i is zero.
public static void printBackwards(int[] array)
{
for(int i =array.length-1; i>= 0; i--)
{
System.out.print(array[i] +" ");
}
}
When you call the methods, this is the syntax you should use:
double avg = average(arrayNums);
System.out.println(avg);
printBackwards(arrayNums);
How to compute the greatest number and display it?
import java.util.Scanner;
public class GreatestNumber {
public static void main(String[] args) {
int [] num = new int [10];
int counter;
int max = 0;
Scanner read = new Scanner(System.in);
for (int i=0; i<num.length; i++)
{
System.out.print("Enter StaffID to be edited:");
num[i]=read.nextInt();
}
}
}
You probably want to compare the numbers as you're reading them. Also, using 0 as a starting value for max will not print out the results you want if all input values are negative. Use Integer.MIN_VALUE instead:
int [] num = new int [10];
int counter;
int max = Integer.MIN_VALUE; // <-- initial value
Scanner read = new Scanner(System.in);
for (int i = 0; i < num.length; i++)
{
System.out.print("Enter StaffID to be edited:");
num[i] = read.nextInt();
if (num[i] > max)
{
max = num[i];
}
}
System.out.print("Max number is:");
System.out.print(max);
Beside the solution provided by other users, you can make a List from the Array and then use an already existing method that finds the maximum value in the list.
List list = Arrays.asList(ArrayUtils.toObject(num));
System.out.println(Collections.max(list)); //Will print the maximum value
This is how you can do it:
Since you are after the largest number, create an integer which has a very small value.
Iterate over the elements of your array. If the element you are currently looking at is larger than the current largest element (initialized in step 1), then update the value of the largest element.
keep track of the current max and update it if you find a higher number, ie
if (num[i] > max)
max = num[i];
Set a running variable max to Integer.MIN_VALUE. Compare it in a loop with every element in the array, and if the array element is bigger, copy its value to max. In the end you have the biggest element in max.