ArrayIndexOutOfBoundsException coming in this array using java? - java

I have an array of numbers in Java and need to output the ones that consist of only duplicated digits. However, my code throws an ArrayIndexOutOfBoundsException. Where is the problem?
int[] inputValues= {122, 2, 22, 11, 234, 333, 000, 5555, 8, 9, 99};
for (int i = 0; i < inputValues.length; i++) {
int numberLength = Integer.toString(inputValues[i]).length();
// System.out.println(numberLength);
if (numberLength > 1) { //more than one digit in the number
String s1 = Integer.toString(inputValues[i]);
String[] numberDigits = s1.split("");
for (int j = 1, k = 1; j < numberDigits.length; k++) {
if (numberDigits[j].equals(numberDigits[k + 1])) {
System.out.println("Duplicate values are:");
//I need to print 22,11,333,000,5555,99
}
}
}
}

There is no condition to stop the inner loop when k gets too big. j never changes in the inner loop, so j < numberDigits.length will either always be true or always be false.

public static void main(String[] args) {
int[] inputValues={122,2,22,11,234,333,000,5555,8,9,99,1000};
System.out.println("Duplicate values are:");
for (int i = 0; i < inputValues.length; i++) {
String strNumber = new Integer(inputValues[i]).toString();// get string from array
if(strNumber.length()>1) // string length must be greater than 1
{
Character firstchar =strNumber.charAt(0); //get first char of string
String strchker =strNumber.replaceAll(firstchar.toString(), ""); //repalce it with black
if(strchker.length()==0) // for duplicate values length must be 0
{
System.out.println(strNumber);
}
}
}
/*
* output will be
* Duplicate values are:
22
11
333
5555
99
*
*
*/
}
This is what you want.....

This line is the culprit here -
for (int j = 1, k = 1; j < numberDigits.length; k++) {
if (numberDigits[j].equals(numberDigits[k + 1])) {
System.out.println("Duplicate values are:");//i need to print 22,11,333,000,5555,99,etc.
}
}
The loop has a condition that's always true as value of j is always 1. Since k keeps on increasing by 1 for each iteration ( which are infinite btw ), the index goes out of array bounds.
Try -
for (int j = 0, k = 1; k < numberDigits.length; k++) {
boolean isDuplicate = true;
if (!numberDigits[j].equals(numberDigits[k])) {
isDuplicate = false;
break;
}
}
if( isDuplicate ) {
System.out.println("Duplicate values are:"+inputValues[i]);
}

Sorry for joining the party late. I think following is the piece of code you’re are looking for
private int[] getDuplicate(int[] arr) {
ArrayList<Integer> duplicate = new ArrayList<Integer>();
for (int item : arr) {
if(item > 9 && areDigitsSame(item)) {
duplicate.add(item);
}
}
int duplicateDigits[] = new int[duplicate.size()];
int index = 0;
for (Integer integer : duplicate) {
duplicateDigits[index ++] = integer;
}
return duplicateDigits;
}
public boolean areDigitsSame(int item) {
int num = item;
int previousDigit = item % 10;
while (num != 0) {
int digit = num % 10;
if (previousDigit != digit) {
return false;
}
num /= 10;
}
return true;
}
Now , use it as below
int[]inputValues={122,2,22,11,234,333,000,5555,8,9,99};
int[] duplicates = getDuplicate(inputValues);
That's all
Enjoy!

public static void main(String[] args) {
String[] inputValues={"122","2","22","11","234","333","000","5555","8","9","99"};
System.out.println("Duplicate values are:");
for (int i = 0; i < inputValues.length; i++) {
String strNumber = inputValues[i];// get string from array
if(strNumber.length()>1) // string length must be greater than 1
{
Character firstchar =strNumber.charAt(0); //get first char of string
String strchker =strNumber.replaceAll(firstchar.toString(), "0"); //repalce it with 0
if(Integer.parseInt(strchker)==0) //if all values are duplictae than result string must be 0
{
System.out.println(strNumber);
}
}
}
}
// /// result will be
/* Duplicate values are:
22
11
333
000
5555
99
*/
if you want int array then you will not able to get "000" as duplicate value.

# line 13: the s1.split("") results to [, 1, 2, 2] for 122 . Hence your numberDigits.length is 4. The loop runs from j = 1 to 3 ( j < numberDigits.length); hence the numberDigits[k + 1 ] is evaluated for index 4 which is unavailable for [, 1, 2, 2].
Another point is worth noting is int[]inputValues will always store 000 as 0 only.
The below mentioned method will take a integer number and will return true and false based on your requirement. It will use xor operator to check repetitive digits.
private static boolean exorEveryCharacter(int currentValue) {
int result = 0;
int previousNumber = -1;
while (currentValue != 0) {
int currentNumber = currentValue % 10;
if(previousNumber == -1){
previousNumber = currentNumber;
}
else{
result = previousNumber ^ currentNumber;
}
currentValue /= 10;
}
return result == 0;
}

Related

How do I write a program to find 0's and 1's in Java?

I want it to take 10 values from the keyboard and find out if any of the 10 inputs contain 0 or 1 and if so, What position is in the array?
example
Input = 9 15 91 1 0 22 31 67 88 33
output = 4 found number 1, at position 2 3 4 7
1 found number 0, at position 5
5 found others, at position 1 6 8 9 10
I can't write any further because I still don't understand. Advise me please
I tried to write it but the output is still not correct.
public static int SequentialSearch(int number[], int key_1, int key_0) {
int looker;
for (looker = 0; looker < number.length; looker++) {
if (number[looker] == key_1)
return looker;
if (number[looker] == key_0)
return looker;
}
return -1;
}
public static void Loopcheck(int number[]) {
int key_1, key_0, others_key;
for (int count_check = 0; count_check < number.length; count_check++) {
if (number[count_check] / 10 == 1 || number[count_check] % 10 == 1) {
key_1 = 1;
break;
} else if (number[count_check] / 10 == 0 || number[count_check] % 10 == 0) {
key_0 = 0;
break;
}
}
}
public static int Print(int number[], int location) {
for (int loop = 0; loop < number.length; loop++)
if (location > -1)
System.out.print(" 0 : " + location);
return 0;
}
public static void main(String[] args) {
Scanner Sc = new Scanner(System.in);
int value1, value0, location, key1;
int[] number = new int[10];
for (int count = 0; count < number.length; count++) {
number[count] = Sc.nextInt();
}
int item1 = 1;
int item0 = 0;
location = SequentialSearch(number, item1, item0);
Loopcheck(number);
Print(number, item1);
}
}
you can use a method like this,
public void haszero(int numbers[])
{
int position;
for(position = 0; position < numbers.size; position++)
{
while(numbers[position] > 0)
{
if(numbers[position] % 10 == 0)
system.out.print("0 at " position)
number=number/10;
}
}
}
and then you can use same method as this for 1.
or the you can also do something like this
for(int position = 0; position < array.size; position++)
{
if (String.valueOf(array[position]).contains("0"))
system.out.print("0 at " position);
}
Since you are looking for a specific character, I would recommend working on String or char array instead. Some code you can consider that will probably give you an idea how to solve a problem:
//part 1
Scanner sc= new Scanner(System.in); //System.in is a standard input stream
System.out.print("Enter first number- ");
int a= sc.nextInt();
System.out.print("Enter second number- ");
int b= sc.nextInt();
System.out.print("Enter third number- ");
int c= sc.nextInt();
// part 2
String Input = String.join(" ",Integer.toString(a),Integer.toString(b),Integer.toString(c));
System.out.println(Input);
// part 3
int i = 0;
while(i<Input.length()){
if(Input.charAt(i)=='0') System.out.println(String.join(" ","0 at position",Integer.toString(i+1)));
if(Input.charAt(i)=='1') System.out.println(String.join(" ","1 at position",Integer.toString(i+1)));
i++;
}
The most impactful advice I would provide is:
store your input as string or char[] instead of int[].
To solve: Create a collection(like a list, or array) to hold your valid indexes, and iterate through your input one letter at a time, adding valid indexes to your collection as they satisfy your condition. Implement a 'PrettyPrint()' that converts your collection into a nice output.
I went ahead a coded a solution that used int arrays. Here are the test results from one of my later tests.
Type 10 values: 0 1 2 3 4 5 6 7 8 9
1 found number 1, at position 2
1 found number 0, at position 1
8 found others, at position 3 4 5 6 7 8 9 10
Type 10 values: 12 23 34 45 127 21 84 0 73 364
3 found number 1, at position 1 5 6
1 found number 0, at position 8
6 found others, at position 2 3 4 7 9 10
Type 10 values:
To exit the program, you just press the Enter key.
My process was to maintain three int arrays. One held the indexes of all the ones. One held the indexes of all the zeros. One held the indexes of all the other values.
I wrote this code step by step, testing each step along the way. I probably ran two or three dozen tests, each testing one small part of the code.
The first thing I did was to get the input loop working correctly. I didn't test for non-numeric input, but that test could be added easily. I didn't limit the input to 10 numbers either. You can type 15 or 20 numbers if you want. Finally, I didn't limit the input to two-digit numbers. The code that looks for a digit should work for any positive integer value.
Next, I wrote a method to determine whether a number contained a particular digit. The method works with any digit, not just zero or one.
After that, it was a matter of getting the output to look correct.
Here's the complete runnable code.
import java.util.Scanner;
public class ZeroAndOne {
public static void main(String[] args) {
new ZeroAndOne().processInput();
}
public void processInput() {
Scanner scanner = new Scanner(System.in);
String line;
do {
System.out.print("Type 10 values: ");
line = scanner.nextLine().trim();
String[] parts = line.split("\\s+");
if (!line.isEmpty()) {
int[] input = new int[parts.length];
for (int index = 0; index < parts.length; index++) {
input[index] = Integer.valueOf(parts[index]);
}
System.out.println(processArray(input));
}
} while (!line.isEmpty());
scanner.close();
}
private String processArray(int[] input) {
int[] zeros = new int[input.length];
int[] ones = new int[input.length];
int[] other = new int[input.length];
int zeroIndex = 0;
int oneIndex = 0;
int otherIndex = 0;
for (int index = 0; index < input.length; index++) {
boolean isOther = true;
if (isDigit(input[index], 0)) {
zeros[zeroIndex++] = index;
isOther = false;
}
if (isDigit(input[index], 1)) {
ones[oneIndex++] = index;
isOther = false;
}
if (isOther) {
other[otherIndex++] = index;
}
}
StringBuilder builder = new StringBuilder();
builder.append(oneIndex);
builder.append(" found number 1, at position ");
builder.append(appendIndexes(ones, oneIndex));
builder.append(System.lineSeparator());
builder.append(zeroIndex);
builder.append(" found number 0, at position ");
builder.append(appendIndexes(zeros, zeroIndex));
builder.append(System.lineSeparator());
builder.append(otherIndex);
builder.append(" found others, at position ");
builder.append(appendIndexes(other, otherIndex));
builder.append(System.lineSeparator());
return builder.toString();
}
private boolean isDigit(int value, int digit) {
if (value == 0 && digit == 0) {
return true;
}
while (value > 0) {
int temp = value / 10;
int remainder = value % 10;
if (remainder == digit) {
return true;
}
value = temp;
}
return false;
}
private StringBuilder appendIndexes(int[] array, int length) {
StringBuilder builder = new StringBuilder();
for (int index = 0; index < length; index++) {
builder.append(array[index] + 1);
if (index < (length - 1)) {
builder.append(" ");
}
}
return builder;
}
}
Assuming that your input is a line containing integer numbers separated by space, you could read them all and then loop the String items via:
String input = Sc.readLine().split(" ");
int positions[] = new int[input.length];
int zeros = 0;
String zeroString = "";
int ones = 0;
String oneString = "";
int others = 0;
String otherString = "";
for (String item : input) {
boolean isOther = true;
String appendix = " " + item;
if (item.indexOf("0") >= 0) {
isOther = false;
zeros++;
zeroString += appendix;
}
if (item.indexOf("1") >= 0) {
isOther = false;
ones++;
oneString += appendix;
}
if (isOther) {
others++;
otherString += appendix;
}
}
System.out.println(ones + " found number 1, at position " + oneString);
System.out.println(zeros + " found number 0, at position " + zeroString);
System.out.println(others + " found others, at position " + otherString);

Find the max value of the same length nails after hammered

I'm trying to solve this problem:
Given an array of positive integers, and an integer Y, you are allowed to replace at most Y array-elements with lesser values. Your goal is for the array to end up with as large a subset of identical values as possible. Return the size of this largest subset.
The array is originally sorted in increasing order, but you do not need to preserve that property.
So, for example, if the array is [10,20,20,30,30,30,40,40,40] and Y = 3, the result should be 6, because you can get six 30s by replacing the three 40s with 30s. If the array is [20,20,20,40,50,50,50,50] and Y = 2, the result should be 5, because you can get five 20s by replacing two of the 50s with 20s.
Below is my solution with O(nlogn) time complexity. (is that right?) I wonder if I can further optimize this solution?
Thanks in advance.
public class Nails {
public static int Solutions(int[] A, int Y) {
int N = A.length;
TreeMap < Integer, Integer > nailMap = new TreeMap < Integer, Integer > (Collections.reverseOrder());
for (int i = 0; i < N; i++) {
if (!nailMap.containsKey(A[i])) {
nailMap.put(A[i], 1);
} else {
nailMap.put(A[i], nailMap.get(A[i]) + 1);
}
}
List < Integer > nums = nailMap.values().stream().collect(Collectors.toList());
if (nums.size() == 1) {
return nums.get(0);
}
//else
int max = nums.get(0);
int longer = 0;
for (int j = 0; j < nums.size(); j++) {
int count = 0;
if (Y < longer) {
count = Y + nums.get(j);
} else {
count = longer + nums.get(j);
}
if (max < count) {
max = count;
}
longer += nums.get(j);
}
return max;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String[] input = scanner.nextLine().replaceAll("\\[|\\]", "").split(",");
System.out.println(Arrays.toString(input));
int[] A = new int[input.length - 1];
int Y = Integer.parseInt(input[input.length - 1]);
for (int i = 0; i < input.length; i++) {
if (i < input.length - 1) {
A[i] = Integer.parseInt(input[i]);
} else {
break;
}
}
int result = Solutions(A, Y);
System.out.println(result);
}
}
}
A C++ implementation would like the following where A is the sorted pin size array and K is the number of times the pins can be hammered.
{1,1,3,3,4,4,4,5,5}, K=2 should give 5 as the answer
{1,1,3,3,4,4,4,5,5,6,6,6,6,6,6}, K=2 should give 6 as the answer
int maxCount(vector<int>& A, int K) {
int n = A.size();
int best = 0;
int count = 1;
for (int i = 0; i < n-K-1; i++) {
if (A[i] == A[i + 1])
count = count + 1;
else
count = 1;
if (count > best)
best = count;
}
int result = max(best+K, min(K+1, n));
return result;
}
Since the array is sorted to begin with, a reasonably straightforward O(n) solution is, for each distinct value, to count how many elements have that value (by iteration) and how many elements have a greater value (by subtraction).
public static int doIt(final int[] array, final int y) {
int best = 0;
int start = 0;
while (start < array.length) {
int end = start;
while (end < array.length && array[end] == array[start]) {
++end;
}
// array[start .. (end-1)] is now the subarray consisting of a
// single value repeated (end-start) times.
best = Math.max(best, end - start + Math.min(y, array.length - end));
start = end; // skip to the next distinct value
}
assert best >= Math.min(y + 1, array.length); // sanity-check
return best;
}
First, iterate through all the nails and create a hash H that stores the number of nails for each size. For [1,2,2,3,3,3,4,4,4], H should be:
size count
1 : 1
2 : 2
3 : 3
4 : 3
Now create an little algorithm to evaluate the maximum sum for each size S, given Y:
BestForSize(S, Y){
total = H[S]
while(Y > 0){
S++
if(Y >= H[S] and S < biggestNailSize){
total += H[S]
Y -= H[S]
}
else{
total += Y
Y = 0
}
}
return total;
}
Your answer should be max(BestForSize(0, Y), BestForSize(1, Y), ..., BestForSize(maxSizeOfNail, Y)).
The complexity is O(n²). A tip to optimize is to start from the end. For example, after you have the maximum value of nails in the size 4, how can you use your answer to find the maximum number of size 3?
Here is my java implementation: First I build a reversed map of each integer and its occurence for example {1,1,1,1,3,3,4,4,5,5} would give {5=2, 4=2, 3=2, 1=4}, then for each integer I calculate the max occurence that we can get of it regarding the K and the occurences of the highest integers in the array.
public static int ourFunction(final int[] A, final int K) {
int length = A.length;
int a = 0;
int result = 0;
int b = 0;
int previousValue = 0;
TreeMap < Integer, Integer > ourMap = new TreeMap < Integer, Integer > (Collections.reverseOrder());
for (int i = 0; i < length; i++) {
if (!ourMap.containsKey(A[i])) {
ourMap.put(A[i], 1);
} else {
ourMap.put(A[i], ourMap.get(A[i]) + 1);
}
}
for (Map.Entry<Integer, Integer> entry : ourMap.entrySet()) {
if( a == 0) {
a++;
result = entry.getValue();
previousValue = entry.getValue();
} else {
if( K < previousValue)
b = K;
else
b = previousValue;
if ( b + entry.getValue() > result )
result = b + entry.getValue();
previousValue += entry.getValue();
}
}
return result;
}
Since the array is sorted, we can have an O(n) solution by iterating and checking if current element is equals to previous element and keeping track of the max length.
static int findMax(int []a,int y) {
int n = a.length,current = 1,max = 0,diff = 0;
for(int i = 1; i< n; i++) {
if(a[i] == a[i-1]) {
current++;
diff = Math.min(y, n-i-1);
max = Math.max(max, current+diff);
}else {
current = 1;
}
}
return max;
}
given int array is not sorted than you should sort
public static int findMax(int []A,int K) {
int current = 1,max = 0,diff = 0;
List<Integer> sorted=Arrays.stream(A).sorted().boxed().collect(Collectors.toList());
for(int i = 1; i< sorted.size(); i++) {
if(sorted.get(i).equals(sorted.get(i-1))) {
current++;
diff = Math.min(K, sorted.size()-i-1);
max = Math.max(max, current+diff);
}else {
current = 1;
}
}
return max;
}
public static void main(String args[]) {
List<Integer> A = Arrays.asList(3,1,5,3,4,4,3,3,5,5,5,1);
int[] Al = A.stream().mapToInt(Integer::intValue).toArray();
int result=findMax(Al, 5);
System.out.println(result);
}

how to determine if a number is a smart number in java?

I have this question I am trying to solve. I have tried coding for the past 4 hours.
An integer is defined to be a Smart number if it is an element in the infinite sequence
1, 2, 4, 7, 11, 16 …
Note that 2-1=1, 4-2=2, 7-4=3, 11-7=4, 16-11=5 so for k>1, the kth element of the sequence is equal to the k-1th element + k-1. For example, for k=6, 16 is the kth element and is equal to 11 (the k-1th element) + 5 ( k-1).
Write function named isSmart that returns 1 if its argument is a Smart number, otherwise it returns 0. So isSmart(11) returns 1, isSmart(22) returns 1 and isSmart(8) returns 0
I have tried the following code to
import java.util.Arrays;
public class IsSmart {
public static void main(String[] args) {
// TODO Auto-generated method stub
int x = isSmart(11);
System.out.println(x);
}
public static int isSmart(int n) {
int[] y = new int[n];
int j = 0;
for (int i = 1; i <= n; i++) {
y[j] = i;
j++;
}
System.out.println(Arrays.toString(y));
for (int i = 0; i <= y.length; i++) {
int diff = 0;
y[j] = y[i+1] - y[i] ;
y[i] = diff;
}
System.out.println(Arrays.toString(y));
for (int i = 0; i < y.length; i++) {
if(n == y[i])
return 1;
}
return 0;
}
}
When I test it with 11 it is giving me 0 but it shouldn't. Any idea how to correct my mistakes?
It can be done in a simpler way as follows
import java.util.Arrays;
public class IsSmart {
public static void main(String[] args) {
int x = isSmart(11);
System.out.println("Ans: "+x);
}
public static int isSmart(int n) {
//------------ CHECK THIS LOGIC ------------//
int[] y = new int[n];
int diff = 1;
for (int i = 1; i < n; i++) {
y[0] =1;
y[i] = diff + y[i-1];
diff++;
}
//------------ CHECK THIS LOGIC ------------//
System.out.println(Arrays.toString(y));
for (int i = 0; i < y.length; i++) {
if(n == y[i])
return 1;
}
return 0;
}
}
One of the problems is the way that your populating your array.
The array can be populated as such
for(int i = 0; i < n; i++) {
y[i] = (i == 0) ? 1 : y[i - 1] + i;
}
The overall application of the function isSmart can be simplified to:
public static int isSmart(int n) {
int[] array = new int[n];
for(int i = 0; i < n; i++) {
array[i] = (i == 0) ? 1 : array[i - 1] + i;
}
for (int i = 0; i < array.length; i++) {
if (array[i] == n) return 1;
}
return 0;
}
Note that you don't need to build an array:
public static int isSmart(int n) {
int smart = 1;
for (int i = 1; smart < n; i++) {
smart = smart + i;
}
return smart == n ? 1 : 0;
}
Here is a naive way to think of it to get you started - you need to fill out the while() loop. The important thing to notice is that:
The next value of the sequence will be the number of items in the sequence + the last item in the sequence.
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
System.out.println(isSmart(11));
}
public static int isSmart(int n) {
ArrayList<Integer> sequence = new ArrayList<Integer>();
// Start with 1 in the ArrayList
sequence.add(1);
// You need to keep track of the index, as well as
// the next value you're going to add to your list
int index = 1; // or number of elements in the sequence
int nextVal = 1;
while (nextVal < n) {
// Three things need to happen in here:
// 1) set nextVal equal to the sum of the current index + the value at the *previous* index
// 2) add nextVal to the ArrayList
// 3) incriment index by 1
}
// Now you can check to see if your ArrayList contains n (is Smart)
if (sequence.contains(n)) { return 1; }
return 0;
}
}
First think of a mathematical solution.
Smart numbers form a sequence:
a0 = 1
an+1 = n + an
This gives a function for smart numbers:
f(x) = ax² + bx + c
f(x + 1) = f(x) + x = ...
So the problem is to find for a given y a matching x.
You can do this by a binary search.
int isSmart(int n) {
int xlow = 1;
int xhigh = n; // Exclusive. For n == 0 return 1.
while (xlow < xhigh) {
int x = (xlow + xhigh)/2;
int y = f(x);
if (y == n) {
return 1;
}
if (y < n) {
xlow = x + 1;
} else {
xhigh = x;
}
}
return 0;
}
Yet smarter would be to use the solution for x and look whether it is an integer:
ax² + bx + c' = 0 where c' = c - n
x = ...
I was playing around with this and I noticed something. The smart numbers are
1 2 4 7 11 16 22 29 ...
If you subtract one you get
0 1 3 6 10 15 21 28 ...
0 1 2 3 4 5 6 7 ...
The above sequence happens to be the sum of the first n numbers starting with 0 which is n*(n+1)/2. So add 1 to that and you get a smart number.
Since n and n+1 are next door to each other you can derive them by reversing the process.
Take 29, subtract 1 = 28, * 2 = 56. The sqrt(56) rounded up is 8. So the 8th smart number (counting from 0) is 29.
Using that information you can detect a smart number without a loop by simply reversing the process.
public static int isSmart(int v) {
int vv = (v-1)*2;
int sq = (int)Math.sqrt(vv);
int chk = (sq*(sq+1))/2 + 1;
return (chk == v) ? 1 : 0;
}
Using a version which supports longs have verified this against the iterative process from 1 to 10,000,000,000.

Can we solve this Sock Merchant problem in less complexity?

I have solved the hackerrank Sock Merchant problem But I want to reduce the complexity of the code(I am not sure that it is possible or not).
John works at a clothing store. He has a large pile of socks that he must pair by color for sale. Given an array of integers representing the color of each sock, determine how many pairs of socks with matching colors there are.
For example, there are n=7 socks with colors ar= [1,2,1,2,1,3,2]. There is one pair of color 1 and one of color 2. There are three odd socks left, one of each color. The number of pairs is 2.
Function Description
Complete the sockMerchant function in the editor below. It must return an integer representing the number of matching pairs of socks that are available.
sockMerchant has the following parameter(s):
n: the number of socks in the pile
ar: the colors of each sock
Input Format
The first line contains an integer n, the number of socks represented in ar.
The second line contains n space-separated integers describing the colors ar[i] of the socks in the pile.
Constraints
1 <= n <= 100
1 <= ar[i] <= 100 where 0 <= i < n
Output Format
Return the total number of matching pairs of socks that John can sell.
Sample Input
9
10 20 20 10 10 30 50 10 20
Sample Output
3
My solutions :
package com.hackerrank.test;
public class Solution {
public static void main(String[] args) {
//Initialize array
int[] arr = new int[]{10, 20, 20, 10, 10, 30, 50, 10, 20};
//Array fr will store frequencies of element
System.out.println("---------------------------------------");
System.out.println(" sockMerchant output " + sockMerchant(9, arr));
System.out.println("---------------------------------------");
}
static int sockMerchant(int n, int[] ar) {
int pairs = 0;
int frequencyArray[] = new int[ar.length];
int frequencyTemp = -1;
for (int i = 0; i < ar.length; i++) {
int count = 1;
for (int j = i + 1; j < ar.length; j++) {
if (ar[i] == ar[j]) {
count++;
frequencyArray[j] = frequencyTemp;
}
}
if (frequencyArray[i] != frequencyTemp) {
frequencyArray[i] = count;
}
}
for (int i = 0; i < frequencyArray.length; i++) {
if (frequencyArray[i] != frequencyTemp) {
int divide = frequencyArray[i] / 2;
pairs += divide;
}
}
return pairs;
}
}
And the output is :
---------------------------------------
sockMerchant frequency 3
---------------------------------------
You can solve this in a single pass (O(n)) using a HashSet, which has O(1) put and lookup time. Each element is already in the set, in which case it gets removed and the pair counter is incremented, or it's not, in which case you add it:
int[] arr = new int[]{10, 20, 20, 10, 10, 30, 50, 10, 20};
HashSet<Integer> unmatched = new HashSet<>();
int pairs = 0;
for(int i = 0; i < arr.length; i++) {
if(!unmatched.add(arr[i])) {
unmatched.remove(arr[i]);
pairs++;
}
}
This works for java 8!!
static int sockMerchant(int n, int[] ar) {
Set<Integer> list = new HashSet<Integer>();
int count = 0;
for(int i= 0; i < n; i++){
if(list.contains(ar[i])){
count++;
list.remove(ar[i]);
}
else{
list.add(ar[i]);
}
}
return count;
}
It can also be solved using a dictionary as follows in Swift:
func sockMerchant(n: Int, ar: [Int]) -> Int {
var dictionary: [Int: Int] = [:]
var totalNumberOfPairs: Int = 0
// Store all array elements in a dictionary
// with element as key and occurrence as value
ar.forEach{
dictionary[$0] = (dictionary[$0] ?? 0) + 1
}
// Iterate over the dictionary while checking for occurrence greater or equal 2.
// If found add the integer division of the occurrence to the current total number of pairs
dictionary.forEach { (key, value) in
if value >= 2 {
totalNumberOfPairs = totalNumberOfPairs + (value / 2)
}
}
return totalNumberOfPairs
}
Here my solution with JAVA for Sock Merchant test on HackerRank
import java.io.*;
import java.util.*;
public class sockMerchant {
public static void main(String[] args) {
Scanner en = new Scanner(System.in);
int n=en.nextInt();
int[] hash = new int[300];
for(int i=0; i<n; i++){
hash[en.nextInt()]++;
}
long res=0;
for(int f: hash){
res+=f/2;
}
System.out.println(res);
}
}
Py3 solution for the problem using dictionaries
def sockMerchant(n, ar):
pair = 0
d = {}
for i in ar:
if i in d:
d[i] += 1
if i not in d:
d[i] = 1
print(d)
for x in d:
u = d[x]//2
pair += u
return pair
Code for python 3
n = 9
ar = [10, 20, 20, 10, 10, 30, 50, 10, 20]
def sockMerchant(n, ar):
totalpair = 0
test= list(set(ar))
for i in test:
pair = 0
for j in ar:
if i==j:
pair+=1
if pair>=2:
totalpair=totalpair+int(pair/2)
return totalpair
print(sockMerchant(n,ar))
We can use a Hash Table, for it. As Hash Table's Complexity is O(1)
Look at below code snippet, i created a dictionary in python i.e. Hash Table having key and value. In dictionary, there only exists a unique Key for each value. So, at start dictionary will be empty. We will loop over the provided list and check values in dictionary keys. If that value is not in dictionary key, it means it is unique, add it to the dictionary. if we find value in dictionary key, simply increment pairs counter and remove that key value pair from hash table i.e. dictionary.
def sockMerchant(n, ar):
hash_map = dict()
pairs = 0
for x in range(len(ar)):
if ar[x] in hash_map.keys():
del hash_map[ar[x]]
pairs += 1
else:
hash_map.setdefault(ar[x])
return pairs
This is my simple code for beginners to understand using c++ which prints the count of numbers of pair in the user-defined vector:
#include <bits/stdc++.h>
using namespace std;
vector<string> split_string(string);
// Complete the sockMerchant function below.
int sockMerchant(int n, vector<int> ar) {
int count=0;
vector<int> x;
for(int i=0;i<n;i++){
if(ar[i]!=0)
{
for(int j=i+1;j<n;j++)
{
if(ar[i]==ar[j]){
count++;
ar[j]=0;
break;
}
}}
}
return count;
}
int main()
{
int a,b;
vector<int> v;
cin>>a;
for(int i=0;i<a;i++){
cin>>b;
v.push_back(b);
}
cout<<sockMerchant(a,v);
}
function sockMerchant(n, ar) {
//Need to initiate a count variable to count pairs and return the value
let count = 0
//sort the given array
ar = ar.sort()
//loop through the sorted array
for (let i=0; i < n-1; i++) {
//if the current item equals to the next item
if(ar[i] === ar[i+1]){
//then that's a pair, increment our count variable
count++
//also increment i to skip the next item
i+=1
}
}
//return the count value
return count
}
sockMerchant(9, [10, 20, 20, 10, 10, 30, 50, 10, 20])
For Javascript
function sockMerchant(n, ar) {
// Create an initial variable to hold the pairs
let pairs = 0;
// create an object to temporarily assign pairs
const temp = {};
// loop through the provided array
for (let n of ar) {
// check if current value already exist in your temp object
if (temp[n] in temp) {
// if current value already exist in temp
// delete the value and increase pairs
delete temp[n];
pairs += 1;
} else {
// else add current value to the object
temp[n] = n;
}
}
// return pairs
return pairs;
}
package com.java.example.sock;
import java.io.IOException;
/**
*
* #author Vaquar Khan
*
*/
public class Solution1 {
// Complete the sockMerchant function below.
/*
* John works at a clothing store. He has a large pile of socks that he must pair by color for sale. Given an array of integers representing the color of each sock, determine how many pairs
* of socks with matching colors there are.
* For example, there are socks with colors . There is one pair of color and one of color . There are three odd socks left, one of each color. The number of pairs is .
*/
static int sockMerchant(int n, int[] ar) {
int counter = 0;
int count = 0;
//
for (int i = 0; i < ar.length; i++) {
count = 1;
//
for (int j = i + 1; j < ar.length; j++) {
if (ar[i] == ar[j]) {
count++;
}
}
if (count % 2 == 0) {
counter++;
}
}
return counter;
}
public static void main(String[] args) throws IOException {
int array[] = { 10, 20, 20 ,10 ,10, 30, 50, 10 ,20};
System.out.println(sockMerchant(9, array));
}
}
Refer below one using HashMap and having complexity O(1)
static int sockMerchant(int n, int[] ar) {
int pairs=0;
Map<Integer, Integer> map = new HashMap<>();
for(int i=0;i<n;i++){
if(map.containsKey(ar[i])){
int count=map.get(ar[i]);
map.put(ar[i],++count);
}
else{
map.put(ar[i],1);
}
}
for(int i : map.values()){
pairs=pairs+(i/2);
}
return pairs;
}
static int sockMerchant(int n, int[] ar) {
int pairs = 0;
for (int i = 0; i < ar.length; i++) {
int counter = 0;
for (int j = 0; j < ar.length; j++) {
if (j < i && ar[j] == ar[i]) break;
if(ar[j]==ar[i]) counter++;
}
pairs+=counter/2;
}
return pairs;
}
def sockMerchant(n, ar):
socks = dict()
pairs = 0
for i in ar:
if i in socks:
socks[i] = socks[i]+1
if i not in socks:
socks[i] = 1
if socks[i]%2 == 0:
pairs += 1
return pairs
This problem can be done easily with a hashset. We can take advantage of the HashSet's ability to not store duplicate elements. Here is the code below.
Set<Integer> set = new HashSet<>();
int pairCount = 0;
for(int i = 0; i < arr.length; i++) {
if(set.add(a[i])
set.add(a[i])
else {
pairCount++;
set.remove(a[i]);
}
}
return pairCount;
/*
* Complete the 'sockMerchant' function below.
*
* The function is expected to return an INTEGER.
* The function accepts following parameters:
* 1. INTEGER n
* 2. INTEGER_ARRAY ar
*/
function sockMerchant(n, ar) {
// Write your code here
let count = [];
for (var i = 0; i < ar.length; i++) {
if (count.hasOwnProperty(ar[i])) {
count[ar[i]]++;
}
else {
count[ar[i]] = 1;
}
}
let number = 0;
for (const key in count) {
number += parseInt(count[key] / 2);
}
return number;
}
My answer in C
int sockMerchant(int n, int ar_count, int* ar) {
int matchcounter =0;// each number repeating count
int paircounter=0;//total pair
int size=0;int i,j,k;
bool num_av=false;//number available or not in new array
int numberarray[n];//creating new (same length) array of length n
for(i=0;i<n;i++){
num_av=false;
for(k=0;k<=size;k++){
if(numberarray[k] == ar[i]){
num_av=true;
break;
}
}
if(!num_av){
size+=1;
numberarray[size-1]=ar[i];
for(j=0;j<n;j++){
if(ar[i]==ar[j]){
matchcounter++;
}
}
paircounter += matchcounter/2;
matchcounter=0;
}
}
return paircounter;
}
I wanted to solve this using Array. Here is my solution for Sock Merchant problem on HackerRank (Java 8):
....
import org.apache.commons.lang3.ArrayUtils;
import java.util.Arrays;
class Result {
public static int sockMerchant(int n, List<Integer> ar) {
int[] arr = ar.stream().mapToInt(i->i).toArray();
int counter = 0;
for(int i = 0; i<n; i++) {
if(arr[i]>0) {
int t = arr[i];
arr[i] = -1;
int j = ArrayUtils.indexOf(arr, t);
if(j == -1) {
continue;
} else {
arr[j] = -1;
counter += 1;
}
} else {
continue;
}
}
return counter;
}
}
This has a O(n) time complexity.
Code for Javascript
const set = new Set()
let count = 0;
for(let i = 0; i < i; i++) {
if (set.has(ar[i])) {
count++;
set.delete(ar[i])
} else {
set.add(ar[i])
}
}
You can count the number of times a number appears in the list and divide them by 2
def sockMerchant(n, ar):
unq = set(ar)
count = 0
for i in unq:
count_vals = ar.count(i)
if count_vals>1:
count = count + int(count_vals/2)
return count
The more easiest way I preferred. Answer in Kotlin
var counter = 0
for (i in 0 until n) {
if (arr[i] != 0) {
loop# for (j in i + 1 until n) {
if (arr[i] == arr[j]) {
counter++
arr[j] = 0
break#loop
}
}
}
}
Commenting for better programming
it can also be solved using the built in Set data type as below (my try) -
function sockMerchant(n, ar) {
// Write your code here
let numberSet = [...new Set(ar)];
let pairs = 0;
for(let i=0;i<numberSet.length;i++){
let count = 0;
ar.filter(x => {
if(x == numberSet[i])
count++;
});
pairs+= count / 2 >= 1 ? Math.trunc(count / 2) : 0;
}
return pairs;
}
Using Python 3:
def sockMerchant(n, ar):
flag = 0
for i in range(n):
if ar[i:].count(ar[i])%2==0:
flag+=1
return flag
Think how you would do it in real life. If someone handed you these socks one-by-one, you'd like think, "Do I have one of these already?" If not, you'd set it down and move on to check on the next sock. When you find one you've already set down, you'd move the pair to the side and count that as another found pair.
Programmatically you may take advantage of a HashSet given it's quick access (constant) and that it only allows for one entry per unique key. Therefore, you can attempt add to the set. Failure to do so means it already exists, count and remove the pair, and continue.
Time-complexity: O(n) [n = number of socks]
Space-complexity: O(m) [m = number of UNIQUE sock types]
Java 8:
public static int sockMerchant(int n, List<Integer> ar)
{
Set<Integer> uniqueSockFound = new HashSet<Integer>();
int countedPairs = 0;
//Iterate through each sock checking if a match has been found already or not
for(Integer sock: ar)
{
//If adding the sock to the set is a success, it doesn't exist yet
//Otherwise, a pair exists, so remove the item and increment the count of pairs
if(!uniqueSockFound.add(sock))
{
countedPairs++;
uniqueSockFound.remove(sock);
}
}
//Return count of pairs
return countedPairs;
}
Here is my solution and it worked for the given set of inputs.
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int size = sc.nextInt();
int[] arr = new int[size];
for (int i = 0 ; i < size ; i++) {
arr[i] = sc.nextInt();
}
int flag = 0;
for (int j = 0; j < size; j++) {
int count = 0;
for(int i = j + 1; i < size ; i++) {
if (arr[j] == arr[i]) {
count++;
}
}
flag += count / 2;
}
System.out.println(flag);
}
}
I solve it with golang
func sockMerchant(n int32, ar []int32) int32 {
// Write your code here
var indexPairs []int;
var count int32;
var operation bool;
for i := 0; i< len(ar)-1; i++{
for j := i+1; j< len(ar); j++{
//check indexPairs
operation = true;
for k := 0; k< len(indexPairs); k++{
if indexPairs[k] == i || indexPairs[k]==j{
operation = false;
}
}
if operation {
if(ar[i]==ar[j]){
count ++;
indexPairs = append(indexPairs, i, j)
}
}
}
}
return count;
}```
using PYTHON language
from itertools import groupby
def sockmerchant(n,ar):
c=0
a=[]
ar.sort()
for k,g in groupby(ar): # in this same elements group into one list
a.append(len(list(g)))
for i in a:
c=c+(i//2)
return c
n=int(input())
ar=list(map(int,input().split(' ')))
print(sockMerchant(n,ar))
function sockMerchant(n, ar){
let res = 0;
let arr= {};
for (let element of ar){
arr[element] = arr[element]+1 || 1
if(arr[element]%2 == 0){
res++;
}
}
return res;
}
sockMerchant(4,[10,10,20,20]);
public static int sockMerchant(int n, List<Integer> ar) {
int pair = 0;
List<Integer> matchedIndices = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (matchedIndices.contains(i)) {
continue;
}
for (int j = 0; j < n; j++) {
if (j == i || matchedIndices.contains(j)) {
continue;
}
if (ar.get(i) == ar.get(j)) {
pair++;
matchedIndices.add(i);
matchedIndices.add(j);
break;
}
}
}
return pair;
}
I will give an example of solving this problem in C++ using unordered_map. It's overkill, to be honest, and it's done with unordered_set as well (removing the element as a replacement for a boolean in the map). But this more clearly shows the coding path to first do everything right, and only after that take an optimization step and convert to unordered_set.
using namespace std;
/*
* Complete the 'sockMerchant' function below.
*
* The function is expected to return an INTEGER.
* The function accepts following parameters:
* 1. INTEGER n
* 2. INTEGER_ARRAY ar
*/
int sockMerchant(int n, vector<int> ar) {
if (n<1 && n>100 ) return 0;
unordered_map<int, bool> scExtract;
int result=0;
// false --first sock finded
// true --second sock funded
for (auto sCol:ar) {
if (sCol<1 && sCol>100 ) return 0;
if (scExtract.find(sCol) != scExtract.end()) {
if ( scExtract[sCol]) {
scExtract[sCol]=false;
} else {
scExtract[sCol]=true;
result++;
}
} else {
scExtract.insert(pair<int, bool>(sCol, false));
}
}
return result;
}

Finding the second highest number in array

I'm having difficulty to understand the logic behind the method to find the second highest number in array. The method used is to find the highest in the array but less than the previous highest (which has already been found). The thing that I still can't figure it out is why || highest_score == second_highest is necessary. For example I input three numbers: 98, 56, 3. Without it, both highest and second highest would be 98. Please explain.
int second highest = score[0];
if (score[i] > second_highest && score[i] < highest_score || highest_score == second_highest)
second_highest = score[i];
I'm not convinced that doing what you did fixes the problem; I think it masks yet another problem in your logic. To find the second highest is actually quite simple:
static int secondHighest(int... nums) {
int high1 = Integer.MIN_VALUE;
int high2 = Integer.MIN_VALUE;
for (int num : nums) {
if (num > high1) {
high2 = high1;
high1 = num;
} else if (num > high2) {
high2 = num;
}
}
return high2;
}
This is O(N) in one pass. If you want to accept ties, then change to if (num >= high1), but as it is, it will return Integer.MIN_VALUE if there aren't at least 2 elements in the array. It will also return Integer.MIN_VALUE if the array contains only the same number.
// Initialize these to the smallest value possible
int highest = Integer.MIN_VALUE;
int secondHighest = Integer.MIN_VALUE;
// Loop over the array
for (int i = 0; i < array.Length; i++) {
// If we've found a new highest number...
if (array[i] > highest) {
// ...shift the current highest number to second highest
secondHighest = highest;
// ...and set the new highest.
highest = array[i];
} else if (array[i] > secondHighest)
// Just replace the second highest
secondHighest = array[i];
}
}
// After exiting the loop, secondHighest now represents the second
// largest value in the array
Edit: Whoops. Thanks for pointing out my mistake, guys. Fixed now.
If the first element which second_highest is set to initially is already the highest element, then it should be reassigned to a new element when the next element is found. That is, it's being initialized to 98, and should be set to 56. But, 56 isn't higher than 98, so it won't be set unless you do the check.
If the highest number appears twice, this will result in the second highest value as opposed to the second element that you would find if you sorted the array.
let array = [0,12,74,26,82,176,189,8,55,3,189];
let highest=0 ;
let secondHighest = 0;
for (let i = 0; i < array.length; i++) {
if (array[i] > highest) {
// ...shift the current highest number to second highest
secondHighest = highest;
// ...and set the new highest.
highest = array[i];
} else if (highest > array[i] > secondHighest) {
// Just replace the second highest
secondHighest = array[i];
}
}
console.log(secondHighest);
The answers I saw wont work if there are two same largest numbers like the below example.
int[] randomIntegers = { 1, 5, 4, 2, 8, 1, 8, 9,9 };
SortedSet<Integer> set = new TreeSet<Integer>();
for (int i: randomIntegers) {
set.add(i);
}
// Remove the maximum value; print the largest remaining item
set.remove(set.last());
System.out.println(set.last());
I have removed it from the Set not from the Array
My idea is that you assume that first and second members of the array are your first max and second max. Then you take each new member of an array and compare it with the 2nd max. Don't forget to compare 2nd max with the 1st one. If it's bigger, just swap them.
public static int getMax22(int[] arr){
int max1 = arr[0];
int max2 = arr[1];
for (int i = 2; i < arr.length; i++){
if (arr[i] > max2)
{
max2 = arr[i];
}
if (max2 > max1)
{
int temp = max1;
max1 = max2;
max2 = temp;
}
}
return max2;
}
public static int secondLargest(int[] input) {
int largest,secondLargest;
if(input[0] > input[1]) {
largest = input[0];
secondLargest = input[1];
}
else {
largest = input[1];
secondLargest = input[0];
}
for(int i = 2; i < input.length; i++) {
if((input[i] <= largest) && input[i] > secondLargest) {
secondLargest = input[i];
}
if(input[i] > largest) {
secondLargest = largest;
largest = input[i];
}
}
return secondLargest;
}
import java.util.Scanner;
public class SecondHighestFromArrayTest {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter size of Array");
int size = scan.nextInt();
int[] arr = new int[size];
for (int i = 0; i < size; i++) {
arr[i] = scan.nextInt();
}
System.out.println("second highest element " + getSecondHighest(arr));
}
public static int getSecondHighest(int arr[]) {
int firstHighest = arr[0];
int secondHighest = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > firstHighest) {
secondHighest = firstHighest;
firstHighest = arr[i];
} else if (arr[i] > secondHighest) {
secondHighest = arr[i];
}
}
return secondHighest;
}
}
If time complexity is not an issue, then You can run bubble sort and within two iterations, you will get your second highest number because in the first iteration of the loop, the largest number will be moved to the last. In the second iteration, the second largest number will be moved next to last.
If you want to 2nd highest and highest number index in array then....
public class Scoller_student {
public static void main(String[] args) {
System.out.println("\t\t\tEnter No. of Student\n");
Scanner scan = new Scanner(System.in);
int student_no = scan.nextInt();
// Marks Array.........
int[] marks;
marks = new int[student_no];
// Student name array.....
String[] names;
names = new String[student_no];
int max = 0;
int sec = max;
for (int i = 0; i < student_no; i++) {
System.out.println("\t\t\tEnter Student Name of id = " + i + ".");
names[i] = scan.next();
System.out.println("\t\t\tEnter Student Score of id = " + i + ".\n");
marks[i] = scan.nextInt();
if (marks[max] < marks[i]) {
sec = max;
max = i;
} else if (marks[sec] < marks[i] && marks[max] != marks[i]) {
sec = i;
}
}
if (max == sec) {
sec = 1;
for (int i = 1; i < student_no; i++) {
if (marks[sec] < marks[i]) {
sec = i;
}
}
}
System.out.println("\t\t\tHigherst score id = \"" + max + "\" Name : \""
+ names[max] + "\" Max mark : \"" + marks[max] + "\".\n");
System.out.println("\t\t\tSecond Higherst score id = \"" + sec + "\" Name : \""
+ names[sec] + "\" Max mark : \"" + marks[sec] + "\".\n");
}
}
public class secondLargestElement
{
public static void main(String[] args)
{
int []a1={1,0};
secondHigh(a1);
}
public static void secondHigh(int[] arr)
{
try
{
int highest,sec_high;
highest=arr[0];
sec_high=arr[1];
for(int i=1;i<arr.length;i++)
{
if(arr[i]>highest)
{
sec_high=highest;
highest=arr[i];
}
else
// The first condition before the || is to make sure that second highest is not actually same as the highest , think
// about {5,4,5}, you don't want the last 5 to be reported as the sec_high
// The other half after || says if the first two elements are same then also replace the sec_high with incoming integer
// Think about {5,5,4}
if(arr[i]>sec_high && arr[i]<highest || highest==sec_high)
sec_high=arr[i];
}
//System.out.println("high="+highest +"sec"+sec_high);
if(highest==sec_high)
System.out.println("All the elements in the input array are same");
else
System.out.println("The second highest element in the array is:"+ sec_high);
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("Not enough elements in the array");
//e.printStackTrace();
}
}
}
You can find Largest and Third largest number of unsorted array as well.
public class ThirdLargestNumber {
public static void main(String[] args) {
int arr[] = { 220, 200, 100, 100, 300, 600, 50, 5000, 125, 785 };
int first = 0, second = 0, third = 0, firstTemp = 0, secondTemp = 0;
for (int i = 0; i <= 9 /*
* Length of array-1. You can use here length
* property of java array instead of hard coded
* value
*/; i++) {
if (arr[i] == first) {
continue;
}
if (arr[i] > first) {
firstTemp = first;
secondTemp = second;
first = arr[i];
second = firstTemp;
if (secondTemp > third) {
third = secondTemp;
}
} else {
if ((arr[i] == second) || (arr[i]) == first) {
continue;
}
if ((arr[i] > second) && (arr[i]) < first) {
secondTemp = second;
second = arr[i];
if (secondTemp > third) {
third = secondTemp;
}
} else {
if (arr[i] > third) {
third = arr[i];
}
}
}
}
// System.out.println("Third largest number: " + third);
System.out.println("Second largest number: " + second);
// System.out.println("Largest number: " + first);
}
}
I think for finding the second Highest no we require these lines,if we can use inbuilt function
int[] randomIntegers = {1, 5, 4, 2, 8, 1, 1, 6, 7, 8, 9};
Arrays.sort(randomIntegers);
System.out.println(randomIntegers[randomIntegers.length-2]);
I am giving solution that's not in JAVA program (written in JavaScript), but it takes o(n/2) iteration to find the highest and second highest number.
Working fiddler link Fiddler link
var num=[1020215,2000,35,2,54546,456,2,2345,24,545,132,5469,25653,0,2315648978523];
var j=num.length-1;
var firstHighest=0,seoncdHighest=0;
num[0] >num[num.length-1]?(firstHighest=num[0],seoncdHighest=num[num.length-1]):(firstHighest=num[num.length-1], seoncdHighest=num[0]);
j--;
for(var i=1;i<=num.length/2;i++,j--)
{
if(num[i] < num[j] )
{
if(firstHighest < num[j]){
seoncdHighest=firstHighest;
firstHighest= num[j];
}
else if(seoncdHighest < num[j] ) {
seoncdHighest= num[j];
}
}
else {
if(firstHighest < num[i])
{
seoncdHighest=firstHighest;
firstHighest= num[i];
}
else if(seoncdHighest < num[i] ) {
seoncdHighest= num[i];
}
}
}
public class SecondandThirdHighestElement {
public static void main(String[] args) {
int[] arr = {1,1,2,3,8,1,2,3,3,3,2,3,101,6,6,7,8,8,1001,99,1,0};
// create three temp variable and store arr of first element in that temp variable so that it will compare with other element
int firsttemp = arr[0];
int secondtemp = arr[0];
int thirdtemp = arr[0];
//check and find first highest value from array by comparing with other elements if found than save in the first temp variable
for (int i = 0; i < arr.length; i++) {
if(firsttemp <arr[i]){
firsttemp = arr[i];
}//if
}//for
//check and find the second highest variable by comparing with other elements in an array and find the element and that element should be smaller than first element array
for (int i = 0; i < arr.length; i++) {
if(secondtemp < arr[i] && firsttemp>arr[i]){
secondtemp = arr[i];
}//if
}//for
//check and find the third highest variable by comparing with other elements in an array and find the element and that element should be smaller than second element array
for (int i = 0; i < arr.length; i++) {
if(thirdtemp < arr[i] && secondtemp>arr[i]){
thirdtemp = arr[i];
}//if
}//for
System.out.println("First Highest Value:"+firsttemp);
System.out.println("Second Highest Value:"+secondtemp);
System.out.println("Third Highest Value:"+thirdtemp);
}//main
}//class
If this question is from the interviewer then please DONT USE SORTING Technique or Don't use any built in methods like Arrays.sort or Collection.sort. The purpose of this questions is how optimal your solution is in terms of performance so the best option would be just implement with your own logic with O(n-1) implementation. The below code is strictly for beginners and not for experienced guys.
public void printLargest(){
int num[] ={ 900,90,6,7,5000,4,60000,20,3};
int largest = num[0];
int secondLargest = num[1];
for (int i=1; i<num.length; i++)
{
if(largest < num[i])
{
secondLargest = largest;
largest = num[i];
}
else if(secondLargest < num[i]){
secondLargest = num[i];
}
}
System.out.println("Largest : " +largest);
System.out.println("Second Largest : "+secondLargest);
}
Problem:
The problem is to get the second largest array element.
Observation:
Second largest number is defined as the number that has the minimum difference when subtracted from the maximum element in the array.
Solution:
This is a two pass solution. First pass is to find the maximum number. Second pass is to find the element that has minimum difference with the maximum element as compared to other array elements. Example: In the array [2, 3, 6, 6, 5] maximum = 6 and second maximum = 5 , since it has the minimum difference to the maximum element 6 - 5 = 1 the solution for second largest = 5
function printSecondMax(myArray) {
var x, max = myArray[0];
// Find maximum element
for(x in myArray){
if(max < myArray[x]){
max = myArray[x];
}
}
var secondMax = myArray[0], diff = max - secondMax;
// Find second max, an element that has min diff with the max
for(x in myArray){
if(diff != 0 && (max - myArray[x]) != 0 && diff > (max - myArray[x])){
secondMax = myArray[x];
diff = max - secondMax;
}
}
console.log(secondMax);
}
Complexity : O(n), This is the simplest way to do this.
For finding maximum element even more efficiently one can look into max heap, a call to max-heapify will take O(log n) time to find the max and then pop-ing the top element gives maximum. To get the second maximum, max-heapify after pop-ing the top and keep pop-ing till you get a number that is less than maximum. That will be the second maximum. This solution has O(n log n) complexity.
private static int SecondBiggest(int[] vector)
{
if (vector == null)
{
throw new ArgumentNullException("vector");
}
if (vector.Length < 2)
{
return int.MinValue;
}
int max1 = vector[0];
int max2 = vector[1];
for (int i = 2; i < vector.Length; ++i)
{
if (max1 > max2 && max1 != vector[i])
{
max2 = Math.Max(max2, vector[i]);
}
else if (max2 != vector[i])
{
max1 = Math.Max(max1, vector[i]);
}
}
return Math.Min(max1, max2);
}
This treats duplicates as the same number. You can change the condition checks if you want to all the biggest and the second biggest to be duplicates.
Please try this one: Using this method, You can fined second largest number in array even array contain random number. The first loop is used to solve the problem if largest number come first index of array.
public class secondLargestnum {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = new int[6];
array[0] = 10;
array[1] = 80;
array[2] = 5;
array[3] = 6;
array[4] = 50;
array[5] = 60;
int tem = 0;
for (int i = 0; i < array.length; i++) {
if (array[0]>array[i]) {
tem = array[0];
array[0] = array[array.length-1];
array[array.length-1] = tem;
}
}
Integer largest = array[0];
Integer second_largest = array[0];
for (int i = 0; i < array.length; i++) {
if (largest<array[i]) {
second_large = largest;
largest = array[i];
}
else if (second_large<array[i]) {
second_large = array[i];
}
}
System.out.println("largest number "+largest+" and second largest number "+second_largest);
}
}
public class SecondHighInIntArray {
public static void main(String[] args) {
int[] intArray=new int[]{2,2,1};
//{2,2,1,12,3,7,9,-1,-5,7};
int secHigh=findSecHigh(intArray);
System.out.println(secHigh);
}
private static int findSecHigh(int[] intArray) {
int highest=Integer.MIN_VALUE;
int sechighest=Integer.MIN_VALUE;
int len=intArray.length;
for(int i=0;i<len;i++)
{
if(intArray[i]>highest)
{
sechighest=highest;
highest=intArray[i];
continue;
}
if(intArray[i]<highest && intArray[i]>sechighest)
{
sechighest=intArray[i];
continue;
}
}
return sechighest;
}
}
Second Largest in O(n/2)
public class SecMaxNum {
// second Largest number with O(n/2)
/**
* #author Rohan Kamat
* #Date Feb 04, 2016
*/
public static void main(String[] args) {
int[] input = { 1, 5, 10, 11, 11, 4, 2, 8, 1, 8, 9, 8 };
int large = 0, second = 0;
for (int i = 0; i < input.length - 1; i = i + 2) {
// System.out.println(i);
int fist = input[i];
int sec = input[i + 1];
if (sec >= fist) {
int temp = fist;
fist = sec;
sec = temp;
}
if (fist >= second) {
if (fist >= large) {
large = fist;
} else {
second = fist;
}
}
if (sec >= second) {
if (sec >= large) {
large = sec;
} else {
second = sec;
}
}
}
}
}
public class SecondHighest {
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
* Find the second largest int item in an unsorted array.
* This solution assumes we have atleast two elements in the array
* SOLVED! - Order N.
* Other possible solution is to solve with Array.sort and get n-2 element.
* However, Big(O) time NlgN
*/
int[] nums = new int[]{1,2,4,3,5,8,55,76,90,34,91};
int highest,cur, secondHighest = -1;
int arrayLength = nums.length;
highest = nums[1] > nums[0] ? nums[1] : nums[0];
secondHighest = nums[1] < nums[0] ? nums[1] : nums[0];
if (arrayLength == 2) {
System.out.println(secondHighest);
} else {
for (int x = 0; x < nums.length; x++) {
cur = nums[x];
int tmp;
if (cur < highest && cur > secondHighest)
secondHighest = cur;
else if (cur > secondHighest && cur > highest) {
tmp = highest;
highest = cur;
secondHighest = tmp;
}
}
System.out.println(secondHighest);
}
}
}
Use following function
`
public static int secHigh(int arr[]){
int firstHigh = 0,secHigh = 0;
for(int x: arr){
if(x > firstHigh){
secHigh = firstHigh;
firstHigh = x;
}else if(x > secHigh){
secHigh = x;
}
}
return secHigh;
}
Function Call
int secondHigh = secHigh(arr);
import java.util.Scanner;
public class SecondLargest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter size of array : ");
int n = sc.nextInt();
int ar[] = new int[n];
for(int i=0;i<n;i++)
{
System.out.print("Enter value for array : ");
ar[i] = sc.nextInt();
}
int m=ar[0],m2=ar[0];
for(int i=0;i<n;i++)
{
if(ar[i]>m)
m=ar[i];
}
for(int i=0;i<n;i++)
{
if(ar[i]>m2 && ar[i]<m)
m2=ar[i];
}
System.out.println("Second largest : "+m2);
sc.close();
}
}
public void findMax(int a[]) {
int large = Integer.MIN_VALUE;
int secondLarge = Integer.MIN_VALUE;
for (int i = 0; i < a.length; i++) {
if (large < a[i]) {
secondLarge = large;
large = a[i];
} else if (a[i] > secondLarge) {
if (a[i] != large) {
secondLarge = a[i];
}
}
}
System.out.println("Large number " + large + " Second Large number " + secondLarge);
}
The above code has been tested with integer arrays having duplicate entries, negative values. Largest number and second largest number are retrived in one pass. This code only fails if array only contains multiple copy of same number like {8,8,8,8} or having only one number.
public class SecondLargestNumber
{
public static void main(String[] args)
{
int[] var={-11,-11,-11,-11,115,-11,-9};
int largest = 0;
int secLargest = 0;
if(var.length == 1)
{
largest = var[0];
secLargest = var[0];
}
else if(var.length > 1)
{
largest= var[0];
secLargest = var[1];
for(int i=1;i<var.length;i++)
{
if(secLargest!=largest)
{
if(var[i]>largest)
{
secLargest = largest;
largest = var[i];
}
else if(var[i]>secLargest && var[i] != largest)
{
secLargest= var[i];
}
}
else
{
if(var[i]>largest)
{
secLargest = largest;
largest = var[i];
}
else
{
secLargest = var[i];
}
}
}
}
System.out.println("Largest: "+largest+" Second Largest: "+secLargest);
}
}
/* Function to print the second largest elements */
void print2largest(int arr[], int arr_size)
{
int i, first, second;
/* There should be atleast two elements */
if (arr_size < 2)
{
printf(" Invalid Input ");
return;
}
first = second = INT_MIN;
for (i = 0; i < arr_size ; i ++)
{
/* If current element is smaller than first
then update both first and second */
if (arr[i] > first)
{
second = first;
first = arr[i];
}
/* If arr[i] is in between first and
second then update second */
else if (arr[i] > second && arr[i] != first)
second = arr[i];
}
if (second == INT_MIN)
printf("There is no second largest elementn");
else
printf("The second largest element is %dn", second);
}
I have got the simplest logic to find the second largest number may be, it's not.
The logic find sum of two number in the array which has the highest value and then check which is greater among two simple............
int ar[]={611,4,556,107,5,55,811};
int sum=ar[0]+ar[1];
int temp=0;
int m=ar[0];
int n=ar[1];
for(int i=0;i<ar.length;i++){
for(int j=i;j<ar.length;j++){
if(i!=j){
temp=ar[i]+ar[j];
if(temp>sum){
sum=temp;
m=ar[i];
n=ar[j];
}
temp=0;
}
}
}
if(m>n){
System.out.println(n);
}
else{
System.out.println(m);
}
The simplest way is -
public class SecondLargest {
public static void main(String[] args) {
int[] arr = { 1, 2, 5, 6, 3 };
int first = Integer.MIN_VALUE;
int second = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
// If current element is smaller than first then update both first
// and second
if (arr[i] > first) {
second = first;
first = arr[i];
}
// If arr[i] is in between first and second then update second
else if (arr[i] > second && arr[i] != first) {
second = arr[i];
}
}
}
}
The second largest element in the array :
IN Java:
class test2{
public static void main(String[] args) {
int a[] = {1,2,3,9,5,7,6,4,8};
Arrays.sort(a);
int aa = a[a.length -2 ];
System.out.println(aa);
}//main
}//end
In Python :
a = [1, 2, 3, 9, 5, 7, 6, 4, 8]
aa = sorted(list(a))
print(aa)
aaa = aa[-2]
print(aaa)

Categories

Resources