Compare consecutive elements in array and sum same values - java

public class LoopTest {
public static void main(String[] args) {
int[] myarr = {12, 12, 12, 8, 15, 15};
//Boolean array to mark the elements,defaults false
boolean[] b = new boolean[myarr.length];
//Compare Consecutive values and mark them true if equal
for (int i = 1; i < myarr.length; i++) {
if (myarr[i - 1] == myarr[i]) {
b[i - 1] = b[i] = true;
}
}
int sum = 0;
//Add all the values in myarr with indices marked as equal
for (int i = 0; i < b.length; i++) {
if (b[i]) {
sum += myarr[i];
}
}
System.out.println(sum);
}
}
Output:
66
Explanation:
12+12+12+15+15
Is there a better/cleaner way to compare values in array and add only values if they are equal, without using utility methods?

You could keep a running count of duplicate items and add them to your sum when the run ends.
int[] myarr = {12, 12, 12, 8, 15, 15};
// assumes > 0 length
int count = 1;
int sum = 0;
for (int i = 1; i < myarr.length; i++) {
if (myarr[i] == myarr[i - 1]) {
count++;
} else {
if (count > 1) {
sum += count * myarr[i - 1];
}
count = 1;
}
}
// handle if last elements are duplicates
if (count > 1) {
sum += count * myarr[myarr.length - 1];
}
System.out.println(sum);

You can solve this with linear efficiency. This program is a little bit cleaner and works in all conditions, checking all the edge cases. It results in the correct answer of 66 for your problem. It loops through the array, and checks if each element is consecutive (same as previous element). If so, it adds the element's value onto the sum. Edge cases need to be included to account for the starting elements of each consecutive block, which have to be added to the sum as well.
private static int consecutiveCompare(int[] array)
{
int sum = 0;
for (int i = 1; i < array.length; i++)
{
if (array[i] == array[i-1])
{
if (i == 1)
{
sum += array[i];
}
else if (array[i] != array[i-2])
{
sum += array[i];
}
sum += array[i];
}
}
return sum;
}

The following code will work:
public class LoopTest {
public static void main(String[] args) {
int[] myarr = {12, 12, 12, 8, 15, 15};
int sum = 0;
int occ = 1;
for (int i = 1; i < myarr.length; i++) {
if (myarr[i - 1] == myarr[i]) {
occ++;
} else {
if (occ > 1) {
sum += (occ * myarr[i - 1]);
}
occ = 1;
}
if (i == myarr.length - 1) {
if (occ > 1) {
sum += (occ * myarr[i - 1]);
}
}
}
System.out.println(sum);
}
}

Haven't tested all edge cases, here is what I have in my mind:
public class LoopTest {
public static void main(String[] args) {
int[] myarr = {1,1,1,2,2,3,3,4};
//Boolean array to mark the elements,defaults false
boolean[] b = new boolean[myarr.length];
//Last value tracker.
int lastVal = myarr[0];
//Count occurrences in a sequence.
int cntr = 1;
//Sum counter.
int sum = 0;
//Compare Consecutive values and mark them true if equal
for (int i = 1; i < myarr.length; i++) {
if (myarr[i] == lastVal) {
cntr++;
//If last sequence mathching.
if (i == myarr.length-1) {
sum += lastVal * cntr;
}
} else {
if (cntr > 1) {
sum += lastVal * cntr;
//Reset counter.
cntr = 1;
}
lastVal = myarr[i];
}
}
System.out.println(sum);
}
}

Related

Given an array of arrays, for each inner array - If the array has < 2 numbers, return 0 else return second smallest number [duplicate]

We are required in our assignment to find the second smallest integer in one array recursively. However, for the sake of understanding the subject more, I want to do it iteratively first (with the help of this website) and recursively on my own.
Unfortunately, doing it iteratively is quite confusing. I understand that the solution is simple but i can't wrap my head around it.
Below is my code, so far:
public static void main(String[] args)
{
int[] elements = {0 , 2 , 10 , 3, -3 };
int smallest = 0;
int secondSmallest = 0;
for (int i = 0; i < elements.length; i++)
{
for (int j = 0; j < elements.length; j++)
{
if (elements[i] < smallest)
{
smallest = elements[i];
if (elements[j] < secondSmallest)
{
secondSmallest = elements[j];
}
}
}
}
System.out.println("The smallest element is: " + smallest + "\n"+ "The second smallest element is: " + secondSmallest);
}
This works for a few numbers, but not all. The numbers change around because the inner if condition isn't as efficient as the outer if condition.
Array rearrangements are forbidden.
Try this one. Second condition is used to catch an event when the smallest number is the first
int[] elements = {-5, -4, 0, 2, 10, 3, -3};
int smallest = Integer.MAX_VALUE;
int secondSmallest = Integer.MAX_VALUE;
for (int i = 0; i < elements.length; i++) {
if(elements[i]==smallest){
secondSmallest=smallest;
} else if (elements[i] < smallest) {
secondSmallest = smallest;
smallest = elements[i];
} else if (elements[i] < secondSmallest) {
secondSmallest = elements[i];
}
}
UPD by #Axel
int[] elements = {-5, -4, 0, 2, 10, 3, -3};
int smallest = Integer.MAX_VALUE;
int secondSmallest = Integer.MAX_VALUE;
for (int i = 0; i < elements.length; i++) {
if (elements[i] < smallest) {
secondSmallest = smallest;
smallest = elements[i];
} else if (elements[i] < secondSmallest) {
secondSmallest = elements[i];
}
}
Here is TimeComlexity Linear O(N):
public static int secondSmallest(int[] arr) {
if(arr==null || arr.length < 2) {
throw new IllegalArgumentException("Input array too small");
}
//implement
int firstSmall = -1;
int secondSmall = -1;
//traverse to find 1st small integer on array
for (int i = 0; i<arr.length;i++)
if (firstSmall == -1 || arr[firstSmall]>arr[i])
firstSmall = i;
//traverse to array find 2 integer, and skip first small
for (int i = 0;i<arr.length;i++) {
if (i != firstSmall && (secondSmall == -1 || arr[secondSmall] > arr[i]))
secondSmall = i;
}
return arr[secondSmall];
}
int[] arr = { 4, 1, 2, 0, 6, 1, 2, 0 };
int smallest = Integer.MAX_VALUE;
int smaller = Integer.MAX_VALUE;
int i = 0;
if (arr.length > 2) {
for (i = 0; i < arr.length; i++) {
if (arr[i] < smallest) {
smaller = smallest;
smallest = arr[i];
} else if (arr[i] < smaller && arr[i] > smallest) {
smaller = arr[i];
}
}
System.out.println("Smallest number is " + smallest);
System.out.println("Smaller number is " + smaller);
} else {
System.out.println("Invalid array !");
}
}
You can do it in O(n) time. Below is the python code
def second_small(A):
if len(A)<2:
print 'Invalid Array...'
return
small = A[0]
second_small = [1]
if small > A[1]:
second_small,small = A[0],A[1]
for i in range(2,len(A)):
if A[i] < second_small and A[i]!=small:
if A[i] < small:
second_small = small
small = A[i]
else:
second_small = A[i]
print small, second_small
A = [12, 13, 1, 10, 34, 1]
second_small(A)
public static int findSecondSmallest(int[] elements) {
if (elements == null || elements.length < 2) {
throw new IllegalArgumentException();
}
int smallest = elements[0];
int secondSmallest = elements[0];
for (int i = 1; i < elements.length; i++) {
if (elements[i] < smallest) {
secondSmallest = smallest;
smallest = elements[i];
}
else if (elements[i] < secondSmallest) {
secondSmallest = elements[i];
}
}
return secondSmallest;
}
Simply, you can do this
int[] arr = new int[]{34, 45, 21, 12, 54, 67, 15};
Arrays.sort(arr);
System.out.println(arr[1]);
Try this one.
public static void main(String args[]){
int[] array = new int[]{10, 30, 15, 8, 20, 4};
int min, secondMin;
if (array[0] > array[1]){
min = array[1];
secondMin = array[0];
}
else{
min = array[0];
secondMin = array[1];
}
for (int i=2; i<array.length; i++){
if (array[i] < min){
secondMin = min;
min = array[i];
}
else if ((array[i] > min) && (array[i] < secondMin)){
secondMin = array[i];
}
}
System.out.println(secondMin);
}
I've used Sort function in javascript
function sumTwoSmallestNumbers(numbers){
numbers = numbers.sort(function(a, b){return a - b; });
return numbers[0] + numbers[1];
};
by providing a compareFunction for the sort functionality array elements are sorted according to the return value of the function.
How about this?
int[] result = Arrays.asList(-3, 4,-1,-2).stream()
.reduce(new int[]{Integer.MIN_VALUE, Integer.MIN_VALUE},
(maxValues, x) -> {
if (x > maxValues[0]) {
maxValues[1] = maxValues[0]; //max becomes second max
maxValues[0] = x;
}
else if (x > maxValues[1]) maxValues[1] = x;
return maxValues;
}
, (x, y) -> x);
class A{
public static void main (String args[]){
int array[]= {-5, -4, 0, 2, 10, 3, -3};
int min;
int second_min;
if(array[0]<array[1]){
min=array[0];
second_min=array[1];
}else{
min=array[1];
second_min=array[0];
}
for(int i=2;i<array.length;i++){
if(second_min > array[i] && min > array[i]){
second_min=min;
min=array[i];
}else if(second_min > array[i] && min < array[i]){
min=min;
second_min=array[i];
}
}
System.out.println(min);
System.out.println(second_min);
}
}
Find the second minimum element of an array in Python, short and simple
def second_minimum(arr):
second = arr[1]
first = arr[0]
for n in arr:
if n < first:
first = n
if n > first and n < second :
second = n
return second
print(second_minimum([-2, 4, 5, -1, 2, 3, 0, -4, 1, 99, -6, -5, -19]))
public static void main(String[] args)
{
int[] elements = {-4 , 2 , 10 , -2, -3 };
int smallest = Integer.MAX_VALUE;
int secondSmallest = Integer.MAX_VALUE;
for (int i = 0; i < elements.length; i++)
{
if (smallest>elements[i])
smallest=elements[i];
}
for (int i = 0; i < elements.length; i++)
{
if (secondSmallest>elements[i] && elements[i]>smallest)
secondSmallest=elements[i];
}
System.out.println("The smallest element is: " + smallest + "\n"+ "The second smallest element is: " + secondSmallest);
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter array size = ");
int size=in.nextInt();
int[] n = new int[size];
System.out.println("Enter "+ size +" values ");
for(int i=0;i<n.length;i++)
n[i] = in.nextInt();
int small=n[0],ssmall=n[0];
// finding small and second small
for(int i=0;i<n.length;i++){
if(small>n[i]){
ssmall=small;
small=n[i];
}else if(ssmall>n[i])
ssmall=n[i];
}
// finding second small if first element itself small
if(small==n[0]){
ssmall=n[1];
for(int i=1;i<n.length;i++){
if(ssmall>n[i]){
ssmall=n[i];
}
}
}
System.out.println("Small "+ small+" sSmall "+ ssmall);
in.close();
}
public static void main(String[] args) {
int arr[] = {6,1,37,-4,12,46,5,64,21,2,-4,-3};
int lowest =arr[0];
int sec_lowest =arr[0];
for(int n : arr){
if (lowest > n)
{
sec_lowest = lowest;
lowest = n;
}
else if (sec_lowest > n && lowest != n)
sec_lowest = n;
}
System.out.println(lowest+" "+sec_lowest);
}
public class SecondSmallestNumberInArray
{
public static void main(String[] args)
{
int arr[] = { 99, 76, 47, 85, 929, 52, 48, 36, 66, 81, 9 };
int smallest = arr[0];
int secondSmallest = arr[0];
System.out.println("The given array is:");
boolean find = false;
boolean flag = true;
for (int i = 0; i < arr.length; i++)
{
System.out.print(arr[i] + " ");
}
System.out.println("");
while (flag)
{
for (int i = 0; i < arr.length; i++)
{
if (arr[i] < smallest)
{
find = true;
secondSmallest = smallest;
smallest = arr[i];
} else if (arr[i] < secondSmallest) {
find = true;
secondSmallest = arr[i];
}
}
if (find) {
System.out.println("\nSecond Smallest number is Array : -> " + secondSmallest);
flag = false;
} else {
smallest = arr[1];
secondSmallest = arr[1];
}
}
}
}
**Output is**
D:\Java>java SecondSmallestNumberInArray
The given array is:
99 76 47 85 929 52 48 36 66 81 9
Second Smallest number is Array : -> 36
D:\Java>
public static int getSecondSmallest(int[] arr){
int smallest = Integer.MAX_VALUE;
int secondSmallest = Integer.MAX_VALUE;
for(int i=0;i<arr.length;i++){
if(smallest > arr[i]){
secondSmallest = smallest;
smallest = arr[i];
}else if (secondSmallest > arr[i] && arr[i] != smallest){
secondSmallest = arr[i];
}
System.out.println(i+" "+smallest+" "+secondSmallest);
}
return secondSmallest;
}
Just gave it a try with some of the test cases and it worked. Please check if it is correct!
Try this ...
First condition checks if both values are less than value in array.
Second condition if value is less than small than smallest=element[i]
else secondSmallest=elements[i]..
public static void main(String[] args)
{
int[] elements = {0 , 2 , 10 , 3, -3 };
int smallest = elements[0];
int secondSmallest = 0;
for (int i = 0; i < elements.Length; i++)
{
if (elements[i]<smallest || elements[i]<secondSmallest )
{
if (elements[i] < smallest )
{
secondSmallest = smallest ;
smallest = elements[i];
}
else
{
secondSmallest = elements[i];
}
}
}
System.out.println("The smallest element is: " + smallest + "\n"+ "The second smallest element is: " + secondSmallest);
}
Try this, program gives solution for both lowest value and second lowest value of array.
Initialize min and second_min with first element of array.Find out the min value and compare it with second_min value . If it (second_min) is greater than current element of array and min value then the second_min value replace with current element of array.
In case arr[]={2,6,12,15,11,0,3} like this , temp variable used to store previous second_min value.
public class Main
{
public static void main(String[] args) {
//test cases.
int arr[]={6,12,1,11,0};
//int arr[]={0,2,10,3,-3};
//int arr[]={0,0,10,3,-3};
//int arr[]={0,2 ,10, 3,-3};
//int arr[]={12,13,1,10,34,1};
//int arr[]={2,6,12,15,11,0,3};
//int arr[]={2,6,12,15,1,0,3};
//int arr[]={2,6,12,15};
//int arr[]={0,1};
//int arr[]={6,16};
//int arr[]={12};
//int arr[]={6,6,6,6,6,6};
int position_min=0;
int min=arr[0];int second_min=arr[0]; int temp=arr[0];
if(arr.length==1)
{
System.out.println("Lowest value is "+arr[0]+"\n Array length should be greater than 1. ");
}
else if(arr.length==2)
{
if(arr[0]>arr[1])
{
min=arr[1];
second_min=arr[0];
position_min=1;
}
else
{
min=arr[0];
second_min=arr[1];
position_min=0;
}
System.out.println("Lowest value is "+min+"\nSecond lowest value is "+second_min);
}
else
{
for( int i=1;i<arr.length;i++)
{
if(min>arr[i])
{
min=arr[i];
position_min=i;
}
}
System.out.println("Lowest value is "+min);
for(int i=1;i<arr.length;i++)
{
if(position_min==i)
{
}
else
{
if(second_min > min & second_min>arr[i])
{
temp=second_min;
second_min=arr[i];
}
else if(second_min == min )
{
second_min=arr[i];
}
}
}
if(second_min==min )
{
second_min=temp;
}
//just for message if in case all elements are same in array.
if(temp==min && second_min==min)
{
System.out.println("There is no Second lowest element in array.");
}
else{
System.out.println("\nSecond lowest value is "+second_min);
}
}
}
}
Here's a Swift version that runs in linear time. Basically, find the smallest number. Then assign the 2nd minimum number as the largest value. Then loop through through the array and find a number greater than the smallest one but also smaller than the 2nd smallest found so far.
func findSecondMinimumElementLinear(in nums: [Int]) -> Int? {
// If the size is less than 2, then returl nil.
guard nums.count > 1 else { return nil }
// First, convert it into a set to reduce duplicates.
let uniqueNums = Array(Set(nums))
// There is no point in sorting if all the elements were the same since it will only leave 1 element
// after the set removed duplicates.
if uniqueNums.count == 1 { return nil }
let min: Int = uniqueNums.min() ?? 0 // O(n)
var secondMinNum: Int = uniqueNums.max() ?? 0 // O(n)
// O(n)
for num in uniqueNums {
if num > min && num < secondMinNum {
secondMinNum = num
}
}
return secondMinNum
}
a straight forward solution in lambda
int[] first = {Integer.MAX_VALUE};
int rslt = IntStream.of( elements ).sorted().dropWhile( n -> {
boolean b = n == first[0] || first[0] == Integer.MAX_VALUE;
first[0] = n;
return( b );
} ).findFirst().orElse( Integer.MAX_VALUE );
the returned OptionalInt from findFirst() can be used to handle the special cases
for elements.length < 2 or elements containing only one value several times
here Integer.MAX_VALUE is returned, if there is no second smallest integer
Well, that should work for you:
function getSecondMin(array){
if(array.length < 2) return NaN;
let min = Math.min(array[0],array[1]);
let secondMin = Math.max(array[0],array[1])
for (let i = 2; i < array.length; i++) {
if(array[i]< min){
secondMin = min
min = array[i]
}
else if(array[i] < secondMin){
secondMin = array[i]
}
}
return secondMin;
}
const secondMin = getSecondMin([1,4,3,100,2])
console.log(secondMin || "invalid array length");

Subset sum negative values

I was wondering how to work with negative values and a negative target, right now my program gives index out of bounds errors whenever negative values are given to these variables. I need my hasSum function work with negative values for this project, I can't just assume positive.
import java.util.Stack;
import java.util.Scanner;
public class subsetSum {
static Scanner input = new Scanner(System.in);
static {
System.out.print("Enter the target (T)" + "\n");
}
/** Set a value for target sum */
static int TARGET_SUM = input.nextInt(); //this is the target
/** Store the sum of current elements stored in stack */
static int sumInStack = 0;
Stack<Integer> stack = new Stack<Integer>();
public static void main(String[] args) {
//the size is S
System.out.println("\n" + "Enter the size of the set (S)");
int values = input.nextInt(); //size = "values"
//value of each size entry
System.out.println("\n" + "Enter the value of each entry for S");
int [] numbers = new int[values];
for(int i = 0; i < values; i++) //for reading array
{
numbers[i] = input.nextInt();
}
if(hasSum(numbers, TARGET_SUM)){
System.out.println("\n" + "Can: ");
subsetSum get = new subsetSum(); // encapsulation
get.populateSubset(numbers, 0, numbers.length);
}else{
System.out.println("\n" + "Cannot");
}
}
//method based on dynamic programming O(sum*length)
public static boolean hasSum(int [] array, int sum)
{
int i;
int len = array.length;
boolean[][] table = new boolean[sum + 1][len + 1]; //this has to be changed for negative
//If sum is zero; empty subset always has a sum 0; hence true
for(i = 0; i <= len; i++){
table[0][i] = true;
}
//If set is empty; no way to find the subset with non zero sum; hence false
for(i = 1; i <= sum; i++){
table[i][0] = false;
}
//calculate the table entries in terms of previous values
for(i = 1; i <= sum; i++)
{
for(int j = 1; j <= len; j++)
{
table[i][j] = table[i][j - 1];
if(!table[i][j] && i >= array[j - 1]){
table[i][j] = table[i - array[j - 1]][j - 1];
}
}
}
return table[sum][len]; //this has to be changed for negative
}
public void populateSubset(int[] data, int fromIndex, int endIndex) {
/*
* Check if sum of elements stored in Stack is equal to the expected
* target sum.
*
* If so, call print method to print the candidate satisfied result.
*/
if (sumInStack >= TARGET_SUM) {
if (sumInStack == TARGET_SUM) {
print(stack);
}
// there is no need to continue when we have an answer
// because nothing we add from here on in will make it
// add to anything less than what we have...
return;
}
for (int currentIndex = fromIndex; currentIndex < endIndex; currentIndex++) {
if (sumInStack + data[currentIndex] <= TARGET_SUM) {
stack.push(data[currentIndex]);
sumInStack += data[currentIndex];
/*
* Make the currentIndex +1, and then use recursion to proceed
* further.
*/
populateSubset(data, currentIndex + 1, endIndex);
sumInStack -= (Integer) stack.pop();
}
}
}
/**
* Print satisfied result. i.e. 5 = 1, 4
*/
private void print(Stack<Integer> stack) {
StringBuilder sb = new StringBuilder();
for (Integer i : stack) {
sb.append(i).append(",");
}
// .deleteCharAt(sb.length() - 1)
System.out.println(sb.deleteCharAt(sb.length() - 1).toString());
}
}
Are you trying to find a sum of subset or a subarray?
If a subset, then a simple recursion could do the trick, e.g.:
public static boolean hasSum(int [] array, int sum)
{
return hasSum(array, 0, 0, sum);
}
private static boolean hasSum(int[] array, int index, int currentSum, int targetSum) {
if (currentSum == targetSum)
return true;
if (index == array.length)
return false;
return hasSum(array, index + 1, currentSum + array[index], targetSum) || // this recursion branch includes current element
hasSum(array, index + 1, currentSum, targetSum); // this doesn't
}
If you're trying to find a subarray, I'd use prefix sums, e.g.:
public static boolean hasSum(int [] array, int sum)
{
int[] prefixSums = new int[array.length];
for (int i = 0; i < prefixSums.length; i++) {
prefixSums[i] = (i == 0) ? array[i] : array[i] + prefixSums[i - 1];
}
for (int to = 0; to < prefixSums.length; to++) {
if (prefixSums[to] == sum)
return true; // interval [0 .. to]
for (int from = 0; from < to; from++) {
if (prefixSums[to] - prefixSums[from] == sum)
return true; // interval (from .. to]
}
}
return false;
}
BTW I think reading the input values from Scanner inside the static initializer is a bad idea, why don't you move them to main()?

Finding the second smallest integer in array

We are required in our assignment to find the second smallest integer in one array recursively. However, for the sake of understanding the subject more, I want to do it iteratively first (with the help of this website) and recursively on my own.
Unfortunately, doing it iteratively is quite confusing. I understand that the solution is simple but i can't wrap my head around it.
Below is my code, so far:
public static void main(String[] args)
{
int[] elements = {0 , 2 , 10 , 3, -3 };
int smallest = 0;
int secondSmallest = 0;
for (int i = 0; i < elements.length; i++)
{
for (int j = 0; j < elements.length; j++)
{
if (elements[i] < smallest)
{
smallest = elements[i];
if (elements[j] < secondSmallest)
{
secondSmallest = elements[j];
}
}
}
}
System.out.println("The smallest element is: " + smallest + "\n"+ "The second smallest element is: " + secondSmallest);
}
This works for a few numbers, but not all. The numbers change around because the inner if condition isn't as efficient as the outer if condition.
Array rearrangements are forbidden.
Try this one. Second condition is used to catch an event when the smallest number is the first
int[] elements = {-5, -4, 0, 2, 10, 3, -3};
int smallest = Integer.MAX_VALUE;
int secondSmallest = Integer.MAX_VALUE;
for (int i = 0; i < elements.length; i++) {
if(elements[i]==smallest){
secondSmallest=smallest;
} else if (elements[i] < smallest) {
secondSmallest = smallest;
smallest = elements[i];
} else if (elements[i] < secondSmallest) {
secondSmallest = elements[i];
}
}
UPD by #Axel
int[] elements = {-5, -4, 0, 2, 10, 3, -3};
int smallest = Integer.MAX_VALUE;
int secondSmallest = Integer.MAX_VALUE;
for (int i = 0; i < elements.length; i++) {
if (elements[i] < smallest) {
secondSmallest = smallest;
smallest = elements[i];
} else if (elements[i] < secondSmallest) {
secondSmallest = elements[i];
}
}
Here is TimeComlexity Linear O(N):
public static int secondSmallest(int[] arr) {
if(arr==null || arr.length < 2) {
throw new IllegalArgumentException("Input array too small");
}
//implement
int firstSmall = -1;
int secondSmall = -1;
//traverse to find 1st small integer on array
for (int i = 0; i<arr.length;i++)
if (firstSmall == -1 || arr[firstSmall]>arr[i])
firstSmall = i;
//traverse to array find 2 integer, and skip first small
for (int i = 0;i<arr.length;i++) {
if (i != firstSmall && (secondSmall == -1 || arr[secondSmall] > arr[i]))
secondSmall = i;
}
return arr[secondSmall];
}
int[] arr = { 4, 1, 2, 0, 6, 1, 2, 0 };
int smallest = Integer.MAX_VALUE;
int smaller = Integer.MAX_VALUE;
int i = 0;
if (arr.length > 2) {
for (i = 0; i < arr.length; i++) {
if (arr[i] < smallest) {
smaller = smallest;
smallest = arr[i];
} else if (arr[i] < smaller && arr[i] > smallest) {
smaller = arr[i];
}
}
System.out.println("Smallest number is " + smallest);
System.out.println("Smaller number is " + smaller);
} else {
System.out.println("Invalid array !");
}
}
You can do it in O(n) time. Below is the python code
def second_small(A):
if len(A)<2:
print 'Invalid Array...'
return
small = A[0]
second_small = [1]
if small > A[1]:
second_small,small = A[0],A[1]
for i in range(2,len(A)):
if A[i] < second_small and A[i]!=small:
if A[i] < small:
second_small = small
small = A[i]
else:
second_small = A[i]
print small, second_small
A = [12, 13, 1, 10, 34, 1]
second_small(A)
public static int findSecondSmallest(int[] elements) {
if (elements == null || elements.length < 2) {
throw new IllegalArgumentException();
}
int smallest = elements[0];
int secondSmallest = elements[0];
for (int i = 1; i < elements.length; i++) {
if (elements[i] < smallest) {
secondSmallest = smallest;
smallest = elements[i];
}
else if (elements[i] < secondSmallest) {
secondSmallest = elements[i];
}
}
return secondSmallest;
}
Simply, you can do this
int[] arr = new int[]{34, 45, 21, 12, 54, 67, 15};
Arrays.sort(arr);
System.out.println(arr[1]);
Try this one.
public static void main(String args[]){
int[] array = new int[]{10, 30, 15, 8, 20, 4};
int min, secondMin;
if (array[0] > array[1]){
min = array[1];
secondMin = array[0];
}
else{
min = array[0];
secondMin = array[1];
}
for (int i=2; i<array.length; i++){
if (array[i] < min){
secondMin = min;
min = array[i];
}
else if ((array[i] > min) && (array[i] < secondMin)){
secondMin = array[i];
}
}
System.out.println(secondMin);
}
I've used Sort function in javascript
function sumTwoSmallestNumbers(numbers){
numbers = numbers.sort(function(a, b){return a - b; });
return numbers[0] + numbers[1];
};
by providing a compareFunction for the sort functionality array elements are sorted according to the return value of the function.
How about this?
int[] result = Arrays.asList(-3, 4,-1,-2).stream()
.reduce(new int[]{Integer.MIN_VALUE, Integer.MIN_VALUE},
(maxValues, x) -> {
if (x > maxValues[0]) {
maxValues[1] = maxValues[0]; //max becomes second max
maxValues[0] = x;
}
else if (x > maxValues[1]) maxValues[1] = x;
return maxValues;
}
, (x, y) -> x);
class A{
public static void main (String args[]){
int array[]= {-5, -4, 0, 2, 10, 3, -3};
int min;
int second_min;
if(array[0]<array[1]){
min=array[0];
second_min=array[1];
}else{
min=array[1];
second_min=array[0];
}
for(int i=2;i<array.length;i++){
if(second_min > array[i] && min > array[i]){
second_min=min;
min=array[i];
}else if(second_min > array[i] && min < array[i]){
min=min;
second_min=array[i];
}
}
System.out.println(min);
System.out.println(second_min);
}
}
Find the second minimum element of an array in Python, short and simple
def second_minimum(arr):
second = arr[1]
first = arr[0]
for n in arr:
if n < first:
first = n
if n > first and n < second :
second = n
return second
print(second_minimum([-2, 4, 5, -1, 2, 3, 0, -4, 1, 99, -6, -5, -19]))
public static void main(String[] args)
{
int[] elements = {-4 , 2 , 10 , -2, -3 };
int smallest = Integer.MAX_VALUE;
int secondSmallest = Integer.MAX_VALUE;
for (int i = 0; i < elements.length; i++)
{
if (smallest>elements[i])
smallest=elements[i];
}
for (int i = 0; i < elements.length; i++)
{
if (secondSmallest>elements[i] && elements[i]>smallest)
secondSmallest=elements[i];
}
System.out.println("The smallest element is: " + smallest + "\n"+ "The second smallest element is: " + secondSmallest);
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter array size = ");
int size=in.nextInt();
int[] n = new int[size];
System.out.println("Enter "+ size +" values ");
for(int i=0;i<n.length;i++)
n[i] = in.nextInt();
int small=n[0],ssmall=n[0];
// finding small and second small
for(int i=0;i<n.length;i++){
if(small>n[i]){
ssmall=small;
small=n[i];
}else if(ssmall>n[i])
ssmall=n[i];
}
// finding second small if first element itself small
if(small==n[0]){
ssmall=n[1];
for(int i=1;i<n.length;i++){
if(ssmall>n[i]){
ssmall=n[i];
}
}
}
System.out.println("Small "+ small+" sSmall "+ ssmall);
in.close();
}
public static void main(String[] args) {
int arr[] = {6,1,37,-4,12,46,5,64,21,2,-4,-3};
int lowest =arr[0];
int sec_lowest =arr[0];
for(int n : arr){
if (lowest > n)
{
sec_lowest = lowest;
lowest = n;
}
else if (sec_lowest > n && lowest != n)
sec_lowest = n;
}
System.out.println(lowest+" "+sec_lowest);
}
public class SecondSmallestNumberInArray
{
public static void main(String[] args)
{
int arr[] = { 99, 76, 47, 85, 929, 52, 48, 36, 66, 81, 9 };
int smallest = arr[0];
int secondSmallest = arr[0];
System.out.println("The given array is:");
boolean find = false;
boolean flag = true;
for (int i = 0; i < arr.length; i++)
{
System.out.print(arr[i] + " ");
}
System.out.println("");
while (flag)
{
for (int i = 0; i < arr.length; i++)
{
if (arr[i] < smallest)
{
find = true;
secondSmallest = smallest;
smallest = arr[i];
} else if (arr[i] < secondSmallest) {
find = true;
secondSmallest = arr[i];
}
}
if (find) {
System.out.println("\nSecond Smallest number is Array : -> " + secondSmallest);
flag = false;
} else {
smallest = arr[1];
secondSmallest = arr[1];
}
}
}
}
**Output is**
D:\Java>java SecondSmallestNumberInArray
The given array is:
99 76 47 85 929 52 48 36 66 81 9
Second Smallest number is Array : -> 36
D:\Java>
public static int getSecondSmallest(int[] arr){
int smallest = Integer.MAX_VALUE;
int secondSmallest = Integer.MAX_VALUE;
for(int i=0;i<arr.length;i++){
if(smallest > arr[i]){
secondSmallest = smallest;
smallest = arr[i];
}else if (secondSmallest > arr[i] && arr[i] != smallest){
secondSmallest = arr[i];
}
System.out.println(i+" "+smallest+" "+secondSmallest);
}
return secondSmallest;
}
Just gave it a try with some of the test cases and it worked. Please check if it is correct!
Try this ...
First condition checks if both values are less than value in array.
Second condition if value is less than small than smallest=element[i]
else secondSmallest=elements[i]..
public static void main(String[] args)
{
int[] elements = {0 , 2 , 10 , 3, -3 };
int smallest = elements[0];
int secondSmallest = 0;
for (int i = 0; i < elements.Length; i++)
{
if (elements[i]<smallest || elements[i]<secondSmallest )
{
if (elements[i] < smallest )
{
secondSmallest = smallest ;
smallest = elements[i];
}
else
{
secondSmallest = elements[i];
}
}
}
System.out.println("The smallest element is: " + smallest + "\n"+ "The second smallest element is: " + secondSmallest);
}
Try this, program gives solution for both lowest value and second lowest value of array.
Initialize min and second_min with first element of array.Find out the min value and compare it with second_min value . If it (second_min) is greater than current element of array and min value then the second_min value replace with current element of array.
In case arr[]={2,6,12,15,11,0,3} like this , temp variable used to store previous second_min value.
public class Main
{
public static void main(String[] args) {
//test cases.
int arr[]={6,12,1,11,0};
//int arr[]={0,2,10,3,-3};
//int arr[]={0,0,10,3,-3};
//int arr[]={0,2 ,10, 3,-3};
//int arr[]={12,13,1,10,34,1};
//int arr[]={2,6,12,15,11,0,3};
//int arr[]={2,6,12,15,1,0,3};
//int arr[]={2,6,12,15};
//int arr[]={0,1};
//int arr[]={6,16};
//int arr[]={12};
//int arr[]={6,6,6,6,6,6};
int position_min=0;
int min=arr[0];int second_min=arr[0]; int temp=arr[0];
if(arr.length==1)
{
System.out.println("Lowest value is "+arr[0]+"\n Array length should be greater than 1. ");
}
else if(arr.length==2)
{
if(arr[0]>arr[1])
{
min=arr[1];
second_min=arr[0];
position_min=1;
}
else
{
min=arr[0];
second_min=arr[1];
position_min=0;
}
System.out.println("Lowest value is "+min+"\nSecond lowest value is "+second_min);
}
else
{
for( int i=1;i<arr.length;i++)
{
if(min>arr[i])
{
min=arr[i];
position_min=i;
}
}
System.out.println("Lowest value is "+min);
for(int i=1;i<arr.length;i++)
{
if(position_min==i)
{
}
else
{
if(second_min > min & second_min>arr[i])
{
temp=second_min;
second_min=arr[i];
}
else if(second_min == min )
{
second_min=arr[i];
}
}
}
if(second_min==min )
{
second_min=temp;
}
//just for message if in case all elements are same in array.
if(temp==min && second_min==min)
{
System.out.println("There is no Second lowest element in array.");
}
else{
System.out.println("\nSecond lowest value is "+second_min);
}
}
}
}
Here's a Swift version that runs in linear time. Basically, find the smallest number. Then assign the 2nd minimum number as the largest value. Then loop through through the array and find a number greater than the smallest one but also smaller than the 2nd smallest found so far.
func findSecondMinimumElementLinear(in nums: [Int]) -> Int? {
// If the size is less than 2, then returl nil.
guard nums.count > 1 else { return nil }
// First, convert it into a set to reduce duplicates.
let uniqueNums = Array(Set(nums))
// There is no point in sorting if all the elements were the same since it will only leave 1 element
// after the set removed duplicates.
if uniqueNums.count == 1 { return nil }
let min: Int = uniqueNums.min() ?? 0 // O(n)
var secondMinNum: Int = uniqueNums.max() ?? 0 // O(n)
// O(n)
for num in uniqueNums {
if num > min && num < secondMinNum {
secondMinNum = num
}
}
return secondMinNum
}
a straight forward solution in lambda
int[] first = {Integer.MAX_VALUE};
int rslt = IntStream.of( elements ).sorted().dropWhile( n -> {
boolean b = n == first[0] || first[0] == Integer.MAX_VALUE;
first[0] = n;
return( b );
} ).findFirst().orElse( Integer.MAX_VALUE );
the returned OptionalInt from findFirst() can be used to handle the special cases
for elements.length < 2 or elements containing only one value several times
here Integer.MAX_VALUE is returned, if there is no second smallest integer
Well, that should work for you:
function getSecondMin(array){
if(array.length < 2) return NaN;
let min = Math.min(array[0],array[1]);
let secondMin = Math.max(array[0],array[1])
for (let i = 2; i < array.length; i++) {
if(array[i]< min){
secondMin = min
min = array[i]
}
else if(array[i] < secondMin){
secondMin = array[i]
}
}
return secondMin;
}
const secondMin = getSecondMin([1,4,3,100,2])
console.log(secondMin || "invalid array length");

java codility Max-Counters

I have been trying to solve the below task:
You are given N counters, initially set to 0, and you have two possible operations on them:
increase(X) − counter X is increased by 1,
max_counter − all counters are set to the maximum value of any counter.
A non-empty zero-indexed array A of M integers is given. This array represents consecutive operations:
if A[K] = X, such that 1 ≤ X ≤ N, then operation K is increase(X),
if A[K] = N + 1 then operation K is max_counter.
For example, given integer N = 5 and array A such that:
A[0] = 3
A[1] = 4
A[2] = 4
A[3] = 6
A[4] = 1
A[5] = 4
A[6] = 4
the values of the counters after each consecutive operation will be:
(0, 0, 1, 0, 0)
(0, 0, 1, 1, 0)
(0, 0, 1, 2, 0)
(2, 2, 2, 2, 2)
(3, 2, 2, 2, 2)
(3, 2, 2, 3, 2)
(3, 2, 2, 4, 2)
The goal is to calculate the value of every counter after all operations.
struct Results {
int * C;
int L;
};
Write a function:
struct Results solution(int N, int A[], int M);
that, given an integer N and a non-empty zero-indexed array A consisting of M integers, returns a sequence of integers representing the values of the counters.
The sequence should be returned as:
a structure Results (in C), or
a vector of integers (in C++), or
a record Results (in Pascal), or
an array of integers (in any other programming language).
For example, given:
A[0] = 3
A[1] = 4
A[2] = 4
A[3] = 6
A[4] = 1
A[5] = 4
A[6] = 4
the function should return [3, 2, 2, 4, 2], as explained above.
Assume that:
N and M are integers within the range [1..100,000];
each element of array A is an integer within the range [1..N + 1].
Complexity:
expected worst-case time complexity is O(N+M);
expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
Here is my solution:
import java.util.Arrays;
class Solution {
public int[] solution(int N, int[] A) {
final int condition = N + 1;
int currentMax = 0;
int countersArray[] = new int[N];
for (int iii = 0; iii < A.length; iii++) {
int currentValue = A[iii];
if (currentValue == condition) {
Arrays.fill(countersArray, currentMax);
} else {
int position = currentValue - 1;
int localValue = countersArray[position] + 1;
countersArray[position] = localValue;
if (localValue > currentMax) {
currentMax = localValue;
}
}
}
return countersArray;
}
}
Here is the code valuation:
https://codility.com/demo/results/demo6AKE5C-EJQ/
Can you give me a hint what is wrong with this solution?
The problem comes with this piece of code:
for (int iii = 0; iii < A.length; iii++) {
...
if (currentValue == condition) {
Arrays.fill(countersArray, currentMax);
}
...
}
Imagine that every element of the array A was initialized with the value N+1. Since the function call Arrays.fill(countersArray, currentMax) has a time complexity of O(N) then overall your algorithm will have a time complexity O(M * N). A way to fix this, I think, instead of explicitly updating the whole array A when the max_counter operation is called you may keep the value of last update as a variable. When first operation (incrementation) is called you just see if the value you try to increment is larger than the last_update. If it is you just update the value with 1 otherwise you initialize it to last_update + 1. When the second operation is called you just update last_update to current_max. And finally, when you are finished and try to return the final values you again compare each value to last_update. If it is greater you just keep the value otherwise you return last_update
class Solution {
public int[] solution(int N, int[] A) {
final int condition = N + 1;
int currentMax = 0;
int lastUpdate = 0;
int countersArray[] = new int[N];
for (int iii = 0; iii < A.length; iii++) {
int currentValue = A[iii];
if (currentValue == condition) {
lastUpdate = currentMax
} else {
int position = currentValue - 1;
if (countersArray[position] < lastUpdate)
countersArray[position] = lastUpdate + 1;
else
countersArray[position]++;
if (countersArray[position] > currentMax) {
currentMax = countersArray[position];
}
}
}
for (int iii = 0; iii < N; iii++) {
if (countersArray[iii] < lastUpdate)
countersArray[iii] = lastUpdate;
}
return countersArray;
}
}
The problem is that when you get lots of max_counter operations you get lots of calls to Arrays.fill which makes your solution slow.
You should keep a currentMax and a currentMin:
When you get a max_counter you just set currentMin = currentMax.
If you get another value, let's call it i:
If the value at position i - 1 is smaller or equal to currentMin you set it to currentMin + 1.
Otherwise you increment it.
At the end just go through the counters array again and set everything less than currentMin to currentMin.
Another solution that I have developed and might be worth considering: http://codility.com/demo/results/demoM658NU-DYR/
This is the 100% solution of this question.
// you can also use imports, for example:
// import java.math.*;
class Solution {
public int[] solution(int N, int[] A) {
int counter[] = new int[N];
int n = A.length;
int max=-1,current_min=0;
for(int i=0;i<n;i++){
if(A[i]>=1 && A[i]<= N){
if(counter[A[i] - 1] < current_min) counter[A[i] - 1] = current_min;
counter[A[i] - 1] = counter[A[i] - 1] + 1;
if(counter[A[i] - 1] > max) max = counter[A[i] - 1];
}
else if(A[i] == N+1){
current_min = max;
}
}
for(int i=0;i<N;i++){
if(counter[i] < current_min) counter[i] = current_min;
}
return counter;
}
}
I'm adding another Java 100 solution with some test cases it they're helpful.
// https://codility.com/demo/results/demoD8J6M5-K3T/ 77
// https://codility.com/demo/results/demoSEJHZS-ZPR/ 100
public class MaxCounters {
// Some testcases
// (1,[1,2,3]) = [1]
// (1,[1]) = [1]
// (1,[5]) = [0]
// (1,[1,1,1,2,3]) = 3
// (2,[1,1,1,2,3,1]) = [4,3]
// (5, [3, 4, 4, 5, 1, 4, 4]) = (1, 0, 1, 4, 1)
public int[] solution(int N, int[] A) {
int length = A.length, maxOfCounter = 0, lastUpdate = 0;
int applyMax = N + 1;
int result[] = new int[N];
for (int i = 0; i < length; ++i ) {
if(A[i] == applyMax){
lastUpdate = maxOfCounter;
} else if (A[i] <= N) {
int position = A[i]-1;
result[position] = result[position] > lastUpdate
? result[position] + 1 : lastUpdate + 1;
// updating the max for future use
if(maxOfCounter <= result[position]) {
maxOfCounter = result[position];
}
}
}
// updating all the values that are less than the lastUpdate to the max value
for (int i = 0; i < N; ++i) {
if(result[i] < lastUpdate) {
result[i] = lastUpdate;
}
}
return result;
}
}
My java solution with a detailed explanation 100% Correctness, 100% Performance :
Time Complexity O(N+M)
public static int[] solution(int N, int[] A) {
int[] counters = new int[N];
//The Max value between all counters at a given time
int max = 0;
//The base Max that all counter should have after the "max counter" operation happens
int baseMax = 0;
for (int i = 0; i < A.length; i++) {
//max counter Operation ==> updating the baseMax
if (A[i] > N) {
// Set The Base Max that all counters should have
baseMax = max;
}
//Verify if the value is bigger than the last baseMax because at any time a "max counter" operation can happen and the counter should have the max value
if (A[i] <= N && counters[A[i] - 1] < baseMax) {
counters[A[i] - 1] = baseMax;
}
//increase(X) Operation => increase the counter value
if (A[i] <= N) {
counters[A[i] - 1] = counters[A[i] - 1] + 1;
//Update the max
max = Math.max(counters[A[i] - 1], max);
}
}
//Set The remaining values to the baseMax as not all counters are guaranteed to be affected by an increase(X) operation in "counters[A[i] - 1] = baseMax;"
for (int j = 0; j < N; j++) {
if (counters[j] < baseMax)
counters[j] = baseMax;
}
return counters;
}
Here is my C++ solution which got 100 on codility. The concept is same as explained above.
int maxx=0;
int lastvalue=0;
void set(vector<int>& A, int N,int X)
{
for ( int i=0;i<N;i++)
if(A[i]<lastvalue)
A[i]=lastvalue;
}
vector<int> solution(int N, vector<int> &A) {
// write your code in C++11
vector<int> B(N,0);
for(unsigned int i=0;i<A.size();i++)
{
if(A[i]==N+1)
lastvalue=maxx;
else
{ if(B[A[i]-1]<lastvalue)
B[A[i]-1]=lastvalue+1;
else
B[A[i]-1]++;
if(B[A[i]-1]>maxx)
maxx=B[A[i]-1];
}
}
set(B,N,maxx);
return B;
}
vector<int> solution(int N, vector<int> &A)
{
std::vector<int> counters(N);
auto max = 0;
auto current = 0;
for (auto& counter : A)
{
if (counter >= 1 && counter <= N)
{
if (counters[counter-1] < max)
counters[counter - 1] = max;
counters[counter - 1] += 1;
if (counters[counter - 1] > current)
current = counters[counter - 1];
}
else if (counter > N)
max = current;
}
for (auto&& counter : counters)
if (counter < max)
counter = max;
return counters;
}
Arrays.fill() invocation inside array interation makes the program O(N^2)
Here is a possible solution which has O(M+N) runtime.
The idea is -
For the second operation, keep track of max value that is achieved through increment, this is our base value till the current iteration, no values can't be less than this.
For the first operation, resetting the value to base value if needed before the increment.
public static int[] solution(int N, int[] A) {
int counters[] = new int[N];
int base = 0;
int cMax = 0;
for (int a : A) {
if (a > counters.length) {
base = cMax;
} else {
if (counters[a - 1] < base) {
counters[a - 1] = base;
}
counters[a - 1]++;
cMax = Math.max(cMax, counters[a - 1]);
}
}
for (int i = 0; i < counters.length; i++) {
if (counters[i] < base) {
counters[i] = base;
}
}
return counters;
}
vector<int> solution(int N, vector<int> &A)
{
std::vector<int> counter(N, 0);
int max = 0;
int floor = 0;
for(std::vector<int>::iterator i = A.begin();i != A.end(); i++)
{
int index = *i-1;
if(*i<=N && *i >= 1)
{
if(counter[index] < floor)
counter[index] = floor;
counter[index] += 1;
max = std::max(counter[index], max);
}
else
{
floor = std::max(max, floor);
}
}
for(std::vector<int>::iterator i = counter.begin();i != counter.end(); i++)
{
if(*i < floor)
*i = floor;
}
return counter;
}
Hera is my AC Java solution. The idea is the same as #Inwvr explained:
public int[] solution(int N, int[] A) {
int[] count = new int[N];
int max = 0;
int lastUpdate = 0;
for(int i = 0; i < A.length; i++){
if(A[i] <= N){
if(count[A[i]-1] < lastUpdate){
count[A[i]-1] = lastUpdate+1;
}
else{
count[A[i]-1]++;
}
max = Math.max(max, count[A[i]-1]);
}
else{
lastUpdate = max;
}
}
for(int i = 0; i < N; i++){
if(count[i] < lastUpdate)
count[i] = lastUpdate;
}
return count;
}
I just got 100 in PHP with some help from the above
function solution($N, $A) {
$B = array(0);
$max = 0;
foreach($A as $key => $a) {
$a -= 1;
if($a == $N) {
$max = max($B);
} else {
if(!isset($B[$a])) {
$B[$a] = 0;
}
if($B[$a] < $max) {
$B[$a] = $max + 1;
} else {
$B[$a] ++;
}
}
}
for($i=0; $i<$N; $i++) {
if(!isset($B[$i]) || $B[$i] < $max) {
$B[$i] = $max;
}
}
return $B;
}
This is another C++ solution to the problem.
The rationale is always the same.
Avoid to set to max counter all the counter upon instruction two, as this would bring the complexity to O(N*M).
Wait until we get another operation code on a single counter.
At this point the algorithm remembers whether it had met a max_counter and set the counter value consequently.
Here the code:
vector<int> MaxCounters(int N, vector<int> &A)
{
vector<int> n(N, 0);
int globalMax = 0;
int localMax = 0;
for( vector<int>::const_iterator it = A.begin(); it != A.end(); ++it)
{
if ( *it >= 1 && *it <= N)
{
// this is an increase op.
int value = *it - 1;
n[value] = std::max(n[value], localMax ) + 1;
globalMax = std::max(n[value], globalMax);
}
else
{
// set max counter op.
localMax = globalMax;
}
}
for( vector<int>::iterator it = n.begin(); it != n.end(); ++it)
*it = std::max( *it, localMax );
return n;
}
100%, O(m+n)
public int[] solution(int N, int[] A) {
int[] counters = new int[N];
int maxAIs = 0;
int minAShouldBe = 0;
for(int x : A) {
if(x >= 1 && x <= N) {
if(counters[x-1] < minAShouldBe) {
counters[x-1] = minAShouldBe;
}
counters[x-1]++;
if(counters[x-1] > maxAIs) {
maxAIs = counters[x-1];
}
} else if(x == N+1) {
minAShouldBe = maxAIs;
}
}
for(int i = 0; i < N; i++) {
if(counters[i] < minAShouldBe) {
counters[i] = minAShouldBe;
}
}
return counters;
}
here is my code, but its 88% cause it takes 3.80 sec for 10000 elements instead of 2.20
class Solution {
boolean maxCalled;
public int[] solution(int N, int[] A) {
int max =0;
int [] counters = new int [N];
int temp=0;
int currentVal = 0;
for(int i=0;i<A.length;i++){
currentVal = A[i];
if(currentVal <=N){
temp = increas(counters,currentVal);
if(temp > max){
max = temp;
}
}else{
if(!maxCalled)
maxCounter(counters,max);
}
}
return counters;
}
int increas (int [] A, int x){
maxCalled = false;
return ++A[x-1];
//return t;
}
void maxCounter (int [] A, int x){
maxCalled = true;
for (int i = 0; i < A.length; i++) {
A[i] = x;
}
}
}
Following my solution in JAVA (100/100).
public boolean isToSum(int value, int N) {
return value >= 1 && value <= N;
}
public int[] solution(int N, int[] A) {
int[] res = new int[N];
int max =0;
int minValue = 0;
for (int i=0; i < A.length; i++){
int value = A[i];
int pos = value -1;
if ( isToSum(value, N)) {
if( res[pos] < minValue) {
res[pos] = minValue;
}
res[pos] += 1;
if (max < res[pos]) {
max = res[pos];
}
} else {
minValue = max;
}
}
for (int i=0; i < res.length; i++){
if ( res[i] < minValue ){
res[i] = minValue;
}
}
return res;
}
my solution is :
public class Solution {
public int[] solution(int N, int[] A) {
int[] counters = new int[N];
int[] countersLastMaxIndexes = new int[N];
int maxValue = 0;
int fixedMaxValue = 0;
int maxIndex = 0;
for (int i = 0; i < A.length; i++) {
if (A[i] <= N) {
if (countersLastMaxIndexes[A[i] - 1] != maxIndex) {
counters[A[i] - 1] = fixedMaxValue;
countersLastMaxIndexes[A[i] - 1] = maxIndex;
}
counters[A[i] - 1]++;
if (counters[A[i] - 1] > maxValue) {
maxValue = counters[A[i] - 1];
}
} else {
maxIndex = i;
fixedMaxValue = maxValue;
}
}
for (int i = 0; i < countersLastMaxIndexes.length; i++) {
if (countersLastMaxIndexes[i] != maxIndex) {
counters[i] = fixedMaxValue;
countersLastMaxIndexes[i] = maxIndex;
}
}
return counters;
}
}
In my Java solution I updated values in solution[] only when needed. And finally updated solution[] with a right values.
public int[] solution(int N, int[] A) {
int[] solution = new int[N];
int maxCounter = 0;
int maxCountersSum = 0;
for(int a: A) {
if(a >= 1 && a <= N) {
if(solution[a - 1] < maxCountersSum)
solution[a - 1] = maxCountersSum;
solution[a - 1]++;
if(solution[a - 1] > maxCounter)
maxCounter = solution[a - 1];
}
if(a == N + 1) {
maxCountersSum = maxCounter;
}
}
for(int i = 0; i < N; i++) {
if(solution[i] < maxCountersSum)
solution[i] = maxCountersSum;
}
return solution;
}
Here's my python solution:
def solution(N, A):
# write your code in Python 3.6
RESP = [0] * N
MAX_OPERATION = N + 1
current_max = 0
current_min = 0
for operation in A:
if operation != MAX_OPERATION:
if RESP[operation-1] <= current_min:
RESP[operation-1] = current_min + 1
else:
RESP[operation-1] += 1
if RESP[operation-1] > current_max:
current_max = RESP[operation-1]
else:
if current_min == current_max:
current_min += 1
else:
current_min = current_max
for i, val in enumerate(RESP):
if val < current_min:
RESP[i] = current_min
return RESP
def sample_method(A,N=5):
initial_array = [0,0,0,0,0]
for i in A:
if(i>=1):
if(i<=N):
initial_array[i-1]+=1
else:
for a in range(len(initial_array)):
initial_array[a]+=1
print i
print initial_array
Here's my solution using python 3.6. The result is 100% correctness but 40% performance (most of them were because of timeout). Still cannot figure out how to optimize this code but hopefully someone can find it useful.
def solution(N, A):
count = [0]*(N+1)
for i in range(0,len(A)):
if A[i] >=1 and A[i] <= N:
count[A[i]] += 1
elif A[i] == (N+1):
count = [max(count)] * len(count)
count.pop(0)
return count
Typescript:
function counters(numCounters: number, operations: number[]) {
const counters = Array(numCounters)
let max = 0
let currentMin = 0
for (const operation of operations) {
if (operation === numCounters + 1) {
currentMin = max
} else {
if (!counters[operation - 1] || counters[operation - 1] < currentMin) {
counters[operation - 1] = currentMin
}
counters[operation - 1] = counters[operation - 1] + 1
if (counters[operation - 1] > max) {
max += 1
}
}
}
for (let i = 0; i < numCounters; i++) {
if (!counters[i] || counters[i] < currentMin) {
counters[i] = currentMin
}
}
return counters
}
console.log(solution=${counters(5, [3, 4, 4, 6, 1, 4, 4])})
100 points JavaScript solution, includes performance improvement to ignore repeated max_counter iterations:
function solution(N, A) {
let max = 0;
let counters = Array(N).fill(max);
let maxCounter = 0;
for (let op of A) {
if (op <= N && op >= 1) {
maxCounter = 0;
if (++counters[op - 1] > max) {
max = counters[op - 1];
}
} else if(op === N + 1 && maxCounter === 0) {
maxCounter = 1;
for (let i = 0; i < counters.length; i++) {
counters[i] = max;
}
}
}
return counters;
}
solution in JAVA (100/100)
class Solution {
public int[] solution(int N, int[] A) {
// write your code in Java SE 8
int[] result = new int[N];
int base = 0;
int max = 0;
int needToChange=A.length;;
for (int k = 0; k < A.length; k++) {
int X = A[k];
if (X >= 1 && X <= N) {
if (result[X - 1] < base) {
result[X - 1] = base;
}
result[X - 1]++;
if (max < result[X - 1]) {
max = result[X - 1];
}
}
if (X == N + 1) {
base = max;
needToChange= X-1;
}
}
for (int i = 0; i < needToChange; i++) {
if (result[i] < base) {
result[i] = base;
}
}
return result;
}
}
My Java solution. It gives 100% but is very long (in comparison). I have used HashMap for storing counters.
Detected time complexity: O(N + M)
import java.util.*;
class Solution {
final private Map<Integer, Integer> counters = new HashMap<>();
private int maxCounterValue = 0;
private int maxCounterValueRealized = 0;
public int[] solution(int N, int[] A) {
if (N < 1) return new int[0];
for (int a : A) {
if (a <= N) {
Integer current = counters.putIfAbsent(a, maxCounterValueRealized + 1);
if (current == null) {
updateMaxCounterValue(maxCounterValueRealized + 1);
} else {
++current;
counters.replace(a, current);
updateMaxCounterValue(current);
}
} else {
maxCounterValueRealized = maxCounterValue;
counters.clear();
}
}
return getCountersArray(N);
}
private void updateMaxCounterValue(int currentCounterValue) {
if (currentCounterValue > maxCounterValue)
maxCounterValue = currentCounterValue;
}
private int[] getCountersArray(int N) {
int[] countersArray = new int[N];
for (int j = 0; j < N; j++) {
Integer current = counters.get(j + 1);
if (current == null) {
countersArray[j] = maxCounterValueRealized;
} else {
countersArray[j] = current;
}
}
return countersArray;
}
}
Here is solution in python with 100 %
Codility Max counter 100%
def solution(N, A):
"""
Solution at 100% - https://app.codility.com/demo/results/trainingUQ95SB-4GA/
Idea is first take the counter array of given size N
take item from main A one by one + 1 and put in counter array , use item as index
keep track of last max operation
at the end replace counter items with max of local or counter item it self
:param N:
:param A:
:return:
"""
global_max = 0
local_max = 0
# counter array
counter = [0] * N
for i, item in enumerate(A):
# take item from original array one by one - 1 - minus due to using item as index
item_as_counter_index = item - 1
# print(item_as_counter_index)
# print(counter)
# print(local_max)
# current element less or equal value in array and greater than 1
# if A[K] = X, such that 1 ≤ X ≤ N, then operation K is increase(X),
if N >= item >= 1:
# max of local_max counter at item_as_counter_index
# increase counter array value and put in counter array
counter[item_as_counter_index] = max(local_max, counter[item_as_counter_index]) + 1
# track the status of global_max counter so far
# this is operation K
global_max = max(global_max, counter[item_as_counter_index])
# if A[K] = N + 1 then operation K is max counter.
elif item == N + 1:
# now operation k is as local max
# here we need to replace all items in array with this global max
# we can do using for loop for array length but that will cost bigo n2 complexity
# example - for i, item in A: counter[i] = global_max
local_max = global_max
# print("global_max each step")
# print(global_max)
# print("local max so far....")
# print(local_max)
# print("counter - ")
# print(counter)
# now counter array - replace all elements which are less than the local max found so far
# all counters are set to the maximum value of any counter
for i, item in enumerate(counter):
counter[i] = max(item, local_max)
return counter
result = solution(1, [3, 4, 4, 6, 1, 4, 4])
print("Sol " + str(result))
enter link description here
Got 100% result with O ( N + M )
class Solution {
public int[] solution(int N, int[] A) {
// write your code in Java SE 8
int max = 0;
int[] counter = new int[N];
int upgrade = 0;
for ( int i = 0; i < A.length; i++ )
{
if ( A[i] <= N )
{
if ( upgrade > 0 && upgrade > counter[A[i] - 1 ] )
{
counter[A[i] - 1] = upgrade;
}
counter[A[i] - 1 ]++;
if ( counter[A[i] - 1 ] > max )
{
max = counter[A[i] - 1 ];
}
}
else
{
upgrade = max;
}
}
for ( int i = 0; i < N; i++ )
{
if ( counter[i] < upgrade)
{
counter[i] = upgrade;
}
}
return counter;
}
}
Java 100%/100%, no imports
public int[] solution(int N, int[] A) {
int[] counters = new int[N];
int currentMax = 0;
int sumOfMaxCounters = 0;
boolean justDoneMaxCounter = false;
for (int i = 0; i < A.length ; i++) {
if (A[i] <= N) {
justDoneMaxCounter = false;
counters[A[i]-1]++;
currentMax = currentMax < counters[A[i]-1] ? counters[A[i]-1] : currentMax;
}else if (!justDoneMaxCounter){
sumOfMaxCounters += currentMax;
currentMax = 0;
counters = new int[N];
justDoneMaxCounter = true;
}
}
for (int j = 0; j < counters.length; j++) {
counters[j] = counters[j] + sumOfMaxCounters;
}
return counters;
}
python solution: 100% 100%
def solution(N, A):
c = [0] * N
max_element = 0
base = 0
for item in A:
if item >= 1 and N >= item:
c[item-1] = max(c[item-1], base) + 1
max_element = max(c[item - 1], max_element)
elif item == N + 1:
base = max_element
for i in range(N):
c[i] = max (c[i], base)
return c
pass
Using applyMax to record max operations
Time complexity:
O(N + M)
class Solution {
public int[] solution(int N, int[] A) {
// write your code in Java SE 8
int max = 0, applyMax = 0;;
int[] result = new int[N];
for (int i = 0; i < A.length; ++i) {
int a = A[i];
if (a == N + 1) {
applyMax = max;
}
if (1 <= a && a <= N) {
result[A[i] - 1] = Math.max(applyMax, result[A[i] - 1]);
max = Math.max(max, ++result[A[i] - 1]);
}
}
for (int i = 0; i < N; ++i) {
if (result[i] < applyMax) {
result[i] = applyMax;
}
}
return result;
}
}

move all even numbers on the first half and odd numbers to the second half in an integer array

I had an interview question which i could not solve.
Write method (not a program) in Java Programming Language that will move all even numbers on the first half and odd numbers to the second half in an integer array.
E.g. Input = {3,8,12,5,9,21,6,10}; Output = {12,8,6,10,3,5,9,21}.
The method should take integer array as parameter and move items in the same array (do not create another array). The numbers may be in different order than original array. This is algorithm test, so try to give as efficient algorithm as you can (possibly linear O(n) algorithm). Avoid using built in functions/API. *
Also some basic intro to what is data structure efficiency
Keep two indices: one to the first odd number and one to the last even number. Swap such numbers and update indices.
(With a lot of help from #manu-fatto's suggestion) I believe this would do it:
private static int[] OddSort(int[] items)
{
int oddPos, nextEvenPos;
for (nextEvenPos = 0;
nextEvenPos < items.Length && items[nextEvenPos] % 2 == 0;
nextEvenPos++) { }
// nextEvenPos is now positioned at the first odd number in the array,
// i.e. it is the next place an even number will be placed
// We already know that items[nextEvenPos] is odd (from the condition of the
// first loop), so we'll start looking for even numbers at nextEvenPos + 1
for (oddPos = nextEvenPos + 1; oddPos < items.Length; oddPos++)
{
// If we find an even number
if (items[oddPos] % 2 == 0)
{
// Swap the values
int temp = items[nextEvenPos];
items[nextEvenPos] = items[oddPos];
items[oddPos] = temp;
// And increment the location for the next even number
nextEvenPos++;
}
}
return items;
}
This algorithm traverses the list exactly 1 time (inspects each element exactly once), so the efficiency is O(n).
// to do this in one for loop
public static void evenodd(int[] integer) {
int i = 0, temp = 0;
int j = integer.length - 1;
while (j >= i) {
// swap if found odd even combo at i and j
if (integer[i] % 2 != 0 && integer[j] % 2 == 0) {
temp = integer[i];
integer[i] = integer[j];
integer[j] = temp;
i++;
j--;
} else {
if (integer[i] % 2 == 0) {
i++;
}
if (integer[j] % 2 == 1) {
j--;
}
}
}
}
#JLRishe,
Your algorithm doesn't maintain the order. For a simple example, say {1,5,2}, you will change the array to {2,5,1}. I could not comment below your post as I am a new user and lack reputations.
public static void sorted(int [] integer) {
int i, j , temp;
for (i = 0; i < integer.length; i++) {
if (integer[i] % 2 == 0) {
for (j = i; j < integer.length; j++) {
if (integer[j] % 2 == 1) {
temp = y[i];
y[i] = y[j];
y[j] = temp;
}
}
}
System.out.println(integer[i]);
}
public static void main(String args[]) {
sorted(new int[]{1, 2,7, 9, 4});
}
}
The answer is 1, 7, 9, 2, 4.
Could it be that you were asked to implement a very basic version of the BubbleSort where the sort value of element e, where e = arr[i], = e%2==1 ? 1 : -1 ?
Regards
Leon
class Demo
{
public void sortArray(int[] a)
{
int len=a.length;
int j=len-1;
for(int i=0;i<len/2+1;i++)
{
if(a[i]%2!=0)
{
while(a[j]%2!=0 && j>(len/2)-1)
j--;
if(j<=(len/2)-1)
break;
a[i]=a[i]+a[j];
a[j]=a[i]-a[j];
a[i]=a[i]-a[j];
}
}
for(int i=0;i<len;i++)
System.out.println(a[i]);
}
public static void main(String s[])
{
int a[]=new int[10];
System.out.println("Enter 10 numbers");
java.util.Scanner sc=new java.util.Scanner(System.in);
for(int i=0;i<10;i++)
{
a[i]=sc.nextInt();
}
new Demo().sortArray(a);
}
}
private static void rearrange(int[] a) {
int i,j,temp;
for(i = 0, j = a.length - 1; i < j ;i++,j--) {
while(a[i]%2 == 0 && i != a.length - 1) {
i++;
}
while(a[j]%2 == 1 && j != 0) {
j--;
}
if(i>j)
break;
else {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
public void sortEvenOddIntegerArray(int[] intArray){
boolean loopRequired = false;
do{
loopRequired = false;
for(int i = 0;i<intArray.length-1;i++){
if(intArray[i] % 2 != 0 && intArray[i+1] % 2 == 0){
int temp = intArray[i];
intArray[i] = intArray[i+1];
intArray[i+1] = temp;
loopRequired = true;
}
}
}while(loopRequired);
}
You can do this with a single loop by moving odd items to the end of the array when you find them.
static void EvensToLeft(int[] items) {
int end = items.length;
for (int i = 0; i < end; i++) {
if (items[i] % 2) {
int t = items[i];
items[i--] = items[--end];
items[end] = t;
}
}
}
Given an input array of length n the inner loop executes exactly n times, and computes the parity of each array element exactly once.
Use two counters i=0 and j=a.length-1 and keep swapping even and odd elements that are in the wrong place.
public int[] evenOddSort(int[] a) {
int i = 0;
int j = a.length - 1;
int temp;
while (i < j) {
if (a[i] % 2 == 0) {
i++;
} else if (a[j] % 2 != 0) {
j--;
} else {
temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
}
return a;
}
public class SeperatOddAndEvenInList {
public static int[] seperatOddAndEvnNos(int[] listOfNumbers) {
int oddNumPointer = 0;
int evenNumPointer = listOfNumbers.length - 1;
while(oddNumPointer <= evenNumPointer) {
if(listOfNumbers[oddNumPointer] % 2 == 0) { //even number, swap to front of last known even number
int temp;
temp = listOfNumbers[oddNumPointer];
listOfNumbers[oddNumPointer] = listOfNumbers[evenNumPointer];
listOfNumbers[evenNumPointer] = temp;
evenNumPointer--;
}
else { //odd number, go ahead... capture next element
oddNumPointer++;
}
}
return listOfNumbers;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int []arr = {3, 8, 12, 5, 9, 21, 6, 10};
int[] seperatedArray = seperatOddAndEvnNos(arr);
for (int i : seperatedArray) {
System.out.println(i);
}
}
}
public class ArraysSortEvensFirst {
public static void main(String[] args) {
int[] arr = generateTestData();
System.out.println(Arrays.toString(arr));
ArraysSortEvensFirst test = new ArraysSortEvensFirst();
test.sortEvensFirst(arr);
}
private static int[] generateTestData() {
int[] arr = {1,3,5,6,9,2,4,5,7};
return arr;
}
public int[] sortEvensFirst(int[] arr) {
int end = arr.length;
int last = arr.length-1;
for(int i=0; i < arr.length; i++) {
// find odd elements, then move to even slots
if(arr[i]%2 > 0) {
int k = findEven(last, arr);
if(k > i) swap(arr, i, k);
last = k;
}
}
System.out.println(Arrays.toString(arr));
return arr;
}
public int findEven(int last, int[] arr) {
for(int k = last; k > 0; k--) {
if(arr[k]%2 == 0) {
return k;
}
}
return -1; // not found;
}
public void swap(int[] arr, int x, int y) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
Output:
[1, 3, 5, 6, 9, 2, 4, 5, 7]
[4, 2, 6, 5, 9, 3, 1, 5, 7]
efficiency is O(log n).
public class TestProg {
public static void main(String[] args) {
int[] input = { 32, 54, 35, 18, 23, 17, 2 };
int front = 0;
int mid = input.length - 1;
for (int start = 0; start < input.length; start++) {
//if current element is odd
if (start < mid && input[start] % 2 == 1) {
//swapping element is also odd?
if (input[mid] % 2 == 1) {
mid--;
start--;
}
//swapping element is not odd then swap
else {
int tmp = input[mid];
input[mid] = input[start];
input[start] = tmp;
mid--;
}
}
}
for (int x : input)
System.out.print(x + " ");
}
}

Categories