Following is the problem-
Given an array of integers as input, return an array that contains the same numbers as that in the input array, but rearranged so that all the even numbers are in front and the odds numbers are at the back. Note that the order of the even numbers and odd numbers should be maintained i.e. if an even number n1 that appears before an even number n2 in the input, then in the output array n1 should appear before n2. The same is true for odd numbers. Also note that in this problem you should not create any new array.
What is done so far is as follows but I am unable to get the expected output.
public class MoveEvenToFront {
static int[] testcase1 = {3, 5, 4, 6, 8, 9, 7, 10};
public static void main(String[] args) {
MoveEvenToFront testInstance = new MoveEvenToFront();
int[] result = testInstance.moveEvenToFront(testcase1);
System.out.print("{");
for (int i = 0; i < result.length; i++) {
if (i > 0) {
System.out.print(",");
}
System.out.print(result[i]);
}
System.out.print("}");
}
public int[] moveEvenToFront(int[] arr) {
int temp = 0;
for (int i = 1; i < arr.length; i++) {
if (arr[i - 1] % 2 != 0) {
temp = arr[i - 1];
arr[i - 1] = arr[i];
arr[i] = temp;
}
}
return arr;
}
}
The expected output for testcase {1,2,3,4,5,6,7,8,10,12} is {2,4,6,8,10,12,1,3,5,7}.
Your algorithm is wrong. You are checking if arr[i-1] is not even and swapping it with arr[i]. If arr[i] is also odd, then you are not checking for it, and it moves to the front even when it is odd.
What you could do is
find the first even number in the array and swap it with first index and increment the index.
then find the second even number and swap it with second index, continue until end of array.
change the method as shown below:
public int[] moveEvenToFront(int[] arr){
int temp=0;
int a=0;
for(int i=0;i<arr.length;i++){
if(arr[i]%2==0){
for (int j=i;j>a;j--){
temp=arr[j-1];
arr[j-1]=arr[j];
arr[j]=temp;
}
a++;
}
}
return arr;
}
Try it straight forward:
public static Integer[] NUMBERS = {3,5,4,6,8,9,7,10};
public static void main(String[] args) {
ArrayList<Integer> ints = new ArrayList<>(Arrays.asList(NUMBERS));
int nextIdx = 0;
for (int idx = 0; idx < ints.size(); idx++) {
if (ints.get(idx) % 2 == 0) ints.add(nextIdx++, ints.remove(idx));
}
System.out.println(ints);
}
OUTPUT:
[4, 6, 8, 10, 3, 5, 9, 7]
public void moveEvenToFront(){
int temp=0;
for(int i=0;i<values.length;i++){
for(int j=i;j<values.length;j++){
if(values[j]%2==0){
temp = values[i];
values[i] = values[j];
values[j] = temp;
}
}
}
after creating values[], the key point of solving this is identifying where there is an even number and switching with values[0]. and increase by 1 so that the even numbers don't disappear. Hope this helps.
Related
Basically I need to find the 2nd maximum number in a array.
Suppose the size of the array is 5 and elements are user-inputed.
Here's my solution:
class Main {
public static void main(String[] args) {
int q = 0;
Scanner sc = new Scanner(System.in);
int[] arr = new int[5];
for (int i = 0; i < 5; i++) {
arr[i] = sc.nextInt();
}
System.out.println(getSecondLargest(arr, 5));
}
public static int getSecondLargest(int[] a, int total) {
int temp;
for (int i = 0; i < total; i++) {
for (int j = i + 1; j < total; j++) {
if (a[i] == a[j]) {
return a[i];
}
if (a[i] > a[j]) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
return a[total - 2];
}
}
Everything works but it fails when the input has the multiple duplicates values of the maximum number. For eg - 5 5 5 4 3 it needs to give 4 as output but it returns 5 as output.
I also tried to simplify code since size is already mentioned:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int q = 0;
Scanner sc = new Scanner(System.in);
int[] arr = new int[5];
for (int i = 0; i < 5; i++) {
arr[i] = sc.nextInt();
}
print2largest(arr, 5);
}
static void print2largest(int arr[], 5) {
Arrays.sort(arr);
System.out.println(arr[3]);
}
}
But for the above simplified code to work perfectly no duplicate values must be present in the array.
How to get 2nd maximum element in case of there are multiple duplicate values.
You can use Java-Stream to do this:
int[] arr = new int[] {3,5, 9, 7, 4, 12};
int secondLargest = Arrays.stream(arr)
.boxed()
.distinct() // remove duplicates
.sorted(Comparator.comparingInt(value -> (int) value).reversed())
.skip(1) // skip the first largest
.findFirst()
.get();
System.out.println(secondLargest);
Output:
9
You can use a TreeSet with reverse comparing:
static void print2largest(int arr[]) {
// Creates a TreeSet where, each time an element is added, will order it
// with a reverse comparator (so the largest values will come first).
// Since this is a set, it'll ignore duplicated elements.
final Set<Integer> set = new TreeSet<>(Collections.reverseOrder());
// Add all values from the input array to this set
for (int value : arr) set.add(value);
// Transforms the set into a list so we can get the second largest element
final List<Integer> sortedValues = new ArrayList(set);
// Returns the second largest element from this set
System.out.println(sortedValues.get(1));
}
You can do two functions.(Simple algorithm)
-First function:
Remove duplicates.
-Second function:
Sort a given array, and return the element located in `[array.length-2]`.
Remember to check if `array.length >= 2`, else,( `array.length = 1` ), return
array[0].
We can find the second largest number in an array in java by sorting the array and returning the 2nd largest number.
public class SecondLargestInArrayExample {
public static int getSecondLargest(int[] a, int total) {
int temp;
for (int i = 0; i < total; i++) {
for (int j = i + 1; j < total; j++) {
if (a[i] > a[j]) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
return a[total - 2];
}
public static void main(String args[]) {
int a[] = {1, 2, 5, 6, 3, 2};
int b[] = {44, 66, 99, 77, 33, 22, 55};
System.out.println("Second Largest: " + getSecondLargest(a, 6));
System.out.println("Second Largest: " + getSecondLargest(b, 7));
}
}
Output:
Second Largest: 5
Second Largest: 77
So assuming that i start with an array [0,0,0,0]. And in this array i will be adding exactly 4 values. Lets say 2,1,3,4. So my main function will look like:
public static void main(String[] args) {
int[] arr = new int[4];
insertSortedInArr(2,arr);
insertSortedInArr(1,arr);
insertSortedInArr(3,arr);
insertSortedInArr(4,arr);
}
I tried an implementation of a method insertSortedInArr() which i also found online, but it is not quite working. I tried to find what goes wrong with it but i couldn't manage to find the bug. This is the method:
public static void insertSortedInArr(int val,int[] arr){
int i;
for(i=0;i<arr.length-1;i++){
if (arr[i] == 0){
arr[i] = val;
return;
}
if (val < arr[i])
// value must be inserted in arr[i]
break;
}
// move everything right
for(int k=i; k<arr.length-1; k++){
arr[k+1]=arr[k];
}
arr[i]=val;
}
My output of this method gives me: [1, 2, 2, 4].
If you could find what's going wrong or have a better implementation of this method it would be appreciated. Thanks.
The problem is in the “move everything right” part.
You are iterating from left to right, but this will overwrite the next element.
Instead, iterate from right to left:
for (int k=arr.length-1; k > i; k--){
arr[k]=arr[k - 1];
}
Since you know already the values, I think we don't even need a loop here. We can just do the following :
public static void insertSorted(int val, int arr[]) {
if(arr[val - 1] == 0) {
arr[val-1] = val;
}
}
or better, just insert the values to array in random order, and use
Arrays.sort(arr);
Hope that it helps.
There can be a minor improvement related to detection of the first free element where available values should be moved:
public static void insertSortedInArr(int val, int[] arr) {
int i;
for (i = 0; i < arr.length; i++) {
if (arr[i] == 0) {
break;
} else if (val < arr[i]) {
int j;
for (j = i + 1; arr[j] != 0 && j < arr.length; j++); // find first 0
for (int k = j; k > i; k--) { // shift elements right to the first free cell
arr[k] = arr[k - 1];
}
break;
}
}
arr[i] = val;
System.out.println(Arrays.toString(arr));
}
Test:
int[] arr = new int[4];
insertSortedInArr(4,arr);
insertSortedInArr(2,arr);
insertSortedInArr(1,arr);
insertSortedInArr(3,arr);
Output:
[4, 0, 0, 0]
[2, 4, 0, 0]
[1, 2, 4, 0]
[1, 2, 3, 4]
I am trying to move every zero to the right side of a given array of integers. But the while loop dose not work correctly and the output is same as input array. How can I fix it?
input : [5,4,0,3,2,0,1,7,0]
expected output: [5,4,7,3,2,1,0,0,0]
public class Examp167 {
public static void exchange(int[] array){
for (int j=0; j<array.length; j++){
if (array[j]==0){
while (array[j] != 0) {
for (int i=array.length-1; i!=j ; i--) {
int temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
}
System.out.print(array[j]+ " ");
}
}
public static void main(String[] args) {
int[] a = new int[] {5,4,0,3,2,0,1,7,0};
exchange(a);
}
}
I can't provide an exact code, but you should look up the dutch national flag problem and try to build up your solution from that. The gist of it is that, whenever you see a 0, swap it with the rightmost element and move the pointer r-- if that makes sense and keep doing it until your left pointer l is l < r.
The pseudo code would be something like this
int l = 0; int r = array.size() - 1;
while(l < r) {
if(array[l] == 0) swap(array[l], array[r--]);
else l++;
}
It should work, but I haven't thought it through, it should give you an idea on a way to solve it at least.
Here is what it could look like in Java:
public class Test {
public static void exchange(int[] array){
int l = 0;
int r = array.length;
while (l < r) {
if(array[l] == 0) {
r--;
int temp = array[l];
array[l] = array[r];
array[r] = temp;
}
else {
l++;
}
}
System.out.println(Arrays.toString(array));
}
public static void main(String[] args) {
int[] a = new int[] {5,4,0,3,2,0,1,7,0};
exchange(a);
}
}
Output:
[5, 4, 7, 3, 2, 1, 0, 0, 0]
If you wouldn't mind the cost of creating a new array, or if you want to keep the original array unchanged, you can consider a new array of the same size as the original one, as the brand new array's values default to zero's, so you just need to put non-zero values at the beginning of the new array and no need to append zeros at the end.
private static int[] exchange(int[] a) {
int[] someArray = new int[a.length];
int count = 0;
for (int num : a) {
if (num != 0) {
someArray[count] = num;
count++;
}
}
return someArray;
}
int[] a = new int[] { 5, 4, 0, 3, 2, 0, 1, 7, 0 };
System.out.println(Arrays.toString(exchange(a)));
The listed "expected output" does not quite reflect what the instructions say. If all you want is to move the zeros to the end, without modifying the order of other entries, then the expected output would be "5, 4, 3, 2, 1, 7, 0, 0, 0", not "5, 4, 7, 3, 2, 1, 0, 0, 0".
The following code for the exchange method leaves the order unmodified:
public static void exchange(int[] array) {
int l = 0;
int r = array.length - 1;
while (l < r) {
if (array[l] == 0) {
for (int i = l + 1; i <= r; i++) {
array[i - 1] = array[i];
}
array[r--] = 0;
}
else l++; //
}
System.out.println(Arrays.toString(array));
}
Figured out the in-place, I was just practicing code and this just popped into my head, O(1) space solution for this problem!
The idea is very similar to the un-stable code, only difference being, instead of tracking the last place and randomly swapping, we tracking from the beginning and do it in a stable manner, by making sure we send non-zeroes to the beginning in a left to right traversal.
Pseudo code:
for(int lastNonZero = 0, cur = 0; cur < nums.size(); cur++) {
if(nums[cur] != 0) {
swap(nums[lastNonZero++], nums[cur]);
}
}
For my program I need to make a 10 element array and the goal is to print out the even numbers from 2 to 20. I have to do this by adding 2 to the beginning element. This is what I have so far. I think I should use a loop as shown but I don't know how to go about adding 2 and printing that out. Thanks!
int[] array = new int[10];
for(int counter=0; counter<array.length; counter++) {
}
if you want program print even number between 2 & 20
for(int i=2;i<=20;i++)
{
if(i%2 == 0)
print(i)
}
Start at 2 and increment by 2 to get the even numbers:
int[] array = new int[10]
for(int counter=2; counter <= 20; counter += 2) {
array[counter/2 - 1] = counter
}
or
int[] array = new int[10]
for(int i=0; i <= 10; i++) {
array[i] = i*2 + 2
}
this is also an option
int i, value;
int nums[] = new int[10];
for (i = 0, value = 2; i < nums.length; value = value + 2, i = i + 1) {
nums[i] = value;
}
for (i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
int[] array = new int[10];
for (int i = 0, j = 1; i < array.length && j <= 20; j++) {
if (j % 2 == 0) {
array[i] = j;
i++;
}
}
System.out.println(Arrays.toString(array));
Java 8: int[] array = IntStream.range(1, 11).map(x -> x * 2).toArray();
Or, to just print: IntStream.range(1, 11).map(x -> x * 2).forEach(System.out::println);
From java-9 you can use IntStream.iterate to create int array
int[] arr= IntStream.iterate(2, i->i<=20, i->i+2).toArray();
for Integer array you can use Stream.iterate
Integer[] ary = Stream.iterate(2, i->i<=20, i->i+2).toArray(Integer[]::new);
Dear Alexis,
Below is an example using do-while.
you can simply define a range of expected even numbers using minVal and maxVal.
Program will execute and return list of ordered even numbers for given range. Assuming input values are correct even numbers. You can improve to apply validations.
public class EvenNumberGenerator {
static int minVal=2; //enter valid min value even number
static int maxVal = 20; //enter valid max value even number
public static void main(String[] args) {
List<Integer> evenNumbers = new ArrayList();
do {
if(minVal % 2 == 0) {
evenNumbers.add(minVal);
}
minVal++;
} while (!evenNumbers.contains(maxVal));
System.out.println(evenNumbers);
// evenNumbers.toArray(); in case you need an array
}
}
OUTPUT
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
Hope it helps!
Using your code as a start, this will work:
int[] array = new int[10];
for(int counter=0; counter<array.length; counter++) {
array[counter] = (counter + 1) * 2;
}
System.out.println(Arrays.toString(array));
The following will also work with Eclipse Collections:
int[] array = IntInterval.evensFromTo(2, 20).toArray();
System.out.println(Arrays.toString(array));
Note: I am a committer for Eclipse Collections
that, given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A.
For example, given A = [1, 3, 6, 4, 1, 2], the function should return 5.
Given A = [1, 2, 3], the function should return 4.
Given A = [−1, −3], the function should return 1.
Write an efficient algorithm for the following assumptions:
import java.util.*;
class Main {
/* Utility function that puts all non-positive
(0 and negative) numbers on left side of
arr[] and return count of such numbers */
static int segregate(int arr[], int size)
{
int j = 0, i;
for (i = 0; i < size; i++) {
if (arr[i] <= 0) {
int temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
// increment count of non-positive
// integers
j++;
}
}
return j;
}
/* Find the smallest positive missing
number in an array that contains
all positive integers */
static int findMissingPositive(int arr[], int size)
{
int i;
// Mark arr[i] as visited by making
// arr[arr[i] - 1] negative. Note that
// 1 is subtracted because index start
// from 0 and positive numbers start from 1
for (i = 0; i < size; i++) {
int x = Math.abs(arr[i]);
if (x - 1 < size && arr[x - 1] > 0)
arr[x - 1] = -arr[x - 1];
}
// Return the first index value at which
// is positive
for (i = 0; i < size; i++)
if (arr[i] > 0)
return i + 1; // 1 is added becuase indexes
// start from 0
return size + 1;
}
/* Find the smallest positive missing
number in an array that contains
both positive and negative integers */
static int findMissing(int arr[], int size)
{
// First separate positive and
// negative numbers
int shift = segregate(arr, size);
int arr2[] = new int[size - shift];
int j = 0;
for (int i = shift; i < size; i++) {
arr2[j] = arr[i];
j++;
}
// Shift the array and call
// findMissingPositive for
// positive part
return findMissingPositive(arr2, j);
}
// main function
public static void main(String[] args)
{
int arr[] = { 0, 10, 2, -10, -20 };
int arr_size = arr.length;
int missing = findMissing(arr, arr_size);
System.out.println("The smallest positive missing number is " + missing);
}
}
}
If you need to use stream, the more straightfoward, but not optimal way to do it is to create an infinite stream, starting at 1 and return the first that is not in arr:
int[] arr = { 1, 3, 6, 4, 1, 2 };
Set<Integer> arrSet = Arrays.stream(arr).boxed().collect(Collectors.toSet());
Optional<Integer> found = IntStream.iterate(1, o -> o + 1).boxed()
.filter(value -> !arrSet.contains(value))
.findFirst();
found.ifPresent(System.out::println);
Output
5
As pointed out this is very inefficient, but in terms of computational complexity I believe is optimal, at least for the worst case i.e. the one you have to look at all the elements.
Below you can find the missing positive integer using Streams -
int ar[] = { 0, 10, 2, -10, -20 };
int max = Arrays.stream(ar).max().getAsInt();
System.err.println("maxvalue "+max);
int val = IntStream.range(1, max).filter(i->!Arrays.stream(ar).anyMatch(x->x==i))
.findFirst().getAsInt();
System.out.println(val);
int[] val1 = IntStream.range(1, max).filter(i->!Arrays.stream(ar).anyMatch(x->x==i)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(val1).forEach(System.out::println);
int[] valEven = IntStream.range(1, max).filter(i->Arrays.stream(val1).anyMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valEven).forEach(System.out::println);
int[] valOdd = IntStream.range(1, max).filter(i->!Arrays.stream(val1).anyMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valOdd).forEach(System.out::println);
int[] valOdd1 = IntStream.range(1, max).filter(i->Arrays.stream(val1).noneMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valOdd1).forEach(System.out::println);
int[] valEven1 = IntStream.range(1, max).filter(i->!Arrays.stream(val1).noneMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valEven1).forEach(System.out::println);
You can also do a mix of stream and primitive int loop:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] numberSet1 = {1, 3, 6, 4, 1, 2};
int[] numberSet2 = {-1, -3};
int[] numberSet3 = {1, 2, 3};
System.out.println(calcularPrimero(numberSet1));
System.out.println(calcularPrimero(numberSet2));
System.out.println(calcularPrimero(numberSet3));
}
public static int calcularPrimero (int[] A) {
//IntStream intStream = Arrays.stream(A).filter(x -> x >= 0).distinct().sorted();
int[] B = Arrays.stream(A).filter(x -> x > 0).distinct().sorted().toArray();
for (int i = 0, index = 1; i < B.length; i++, index++) {
if (index != B[i]) {
return index;
}
}
return B.length + 1;
}
}