given an array of integers, segregate even and odd numbers in the array. All the even numbers should be present first, and then the odd numbers.
Examples:
Input: arr[] = 1 9 5 3 2 6 7 11
Output: 2 6 5 3 1 9 7 11
Input: arr[] = 1 3 2 4 7 6 9 10
Output: 2 4 6 10 7 1 9 3
public class Segregate_even_odd_numbers {
public static void main(String[] args) {
int a[]= { 1, 3, 2, 4, 7, 6, 9, 10 };
int n=a.length;
int ind=0;
for(int i=0;i<n;i++){
if(a[i]%2==0){
a[ind]=a[i];
ind++;
}
}
for(int i=0;i<n;i++){
if(a[i]%2!=0){
a[ind]=a[i];
ind++;
}
}
for(int i=0;i<n;i++){
System.out.println(a[i] + " ");
}
System.out.println("");
}
}
I am getting output like this
2
4
6
10
7
9
9
10
0th index and 1st index not calculate.
what mistake I made, please guide me.
You're program is almost correct, but needs little modification, below is the implementation and explanation
public class Segregate_even_odd_numbers {
public static void main(String[] args) {
int a[] = { 1, 9, 5, 3, 2, 6, 7, 11 };
int n = a.length;
int evenIndex = 0;
for (int i = 0; i < n; i++) {
if (a[i] % 2 == 0) {
int temp = a[i];
a[i] = a[evenIndex];
a[evenIndex] = temp;
evenIndex++;
}
}
for (int i = 0; i < n; i++) {
System.out.print(a[i] + " ");
}
System.out.println("");
} }
What are we doing here:
We maintain a evenIndex pointer at 0 index
Whenever we find any Even value we swap it with evenIndex i.e.., arr[evenIndex] = arr[i] and place arr[i] = arr[evenIndex]
This code works does not modify any values if you pass an array with only Even Numbers or Odd Numbers
Time Complexity : O(n)
Space Complexity : O(1)
This can also be accomplished by sorting the array based on the value of each element modulo 2.
int[] a= { 1, 3, 2, 4, 7, 6, 9, 10 };
int[] res = Arrays.stream(a).boxed().sorted(Comparator.comparingInt(x -> x & 1))
.mapToInt(i -> i).toArray();
System.out.println(Arrays.toString(res));
I have a 2D array where I want to find the middle position between two given position:
below eg shows the indexes at each position.
00, 01, 02, 03
10, 11, 12, 13
20, 21, 22, 23
30, 31, 32, 33
Inputs:
For position 23 and 33 I should get the output position 31.
Here the inputs are iStart is 2 and jStart is 3, similarly iEnd is 3 and jEnd is 3
The expected o/p is i_mid = 3 and j_mid = 1
For position 00 and 22 I should get the output position 11.
Here the inputs are iStart is 0 and jStart is also 0, similarly iEnd and jEnd are equal to 1
The expected o/p is i_mid = 1 and j_mid = 1
For position 02 and 23 I should get the output position 12.
Here the inputs are iStart is 0 and jStart is 2, similarly iEnd is 2 and jEnd is 3
The expected o/p is i_mid = 1 and j_mid = 2
For position 10 and 31 I should get the output position 20.
Here the inputs are iStart is 3 and jStart is 1, similarly iEnd is 3 and jEnd is 1
The expected o/p is i_mid = 2 and j_mid = 0
I released that to calculate we should also know the length of the array as it is nxm matrix, ie. max value of i can go is n and max value of j can go is m.
therefor for a nxm array iMax will be n and jMax will be m
Now the function can be represents as:
void getMiddle(int iStart, int jStart, int iEnd, int jEnd, int iMax, int jMax) {
//We need to find the mid_i and mid_j of the input positions
System.out.println("midd_i = "+ mid_i +" and midd_j = "+mid_j);
}
I solved this via a brute force approach, however I'm looking for an optimal solution.
In my approach, first I find the number of elements that can come between the given position and then I divided the number of element by 2 and traverse the position till half of the elements that can come as that point will be the mid, my solution is as followed:
void getMiddle(int iStart, int jStart, int iEnd, int jEnd, int jMax) {
int numberOfRows = (iEnd - iStart) + 1;
int totalElementsInRows = jMax * numberOfRows;
int eliminateStartElements = jStart;
int eliminateEndElements = (jMax - 1) - jEnd;
int totalElementsPresentBetweenPositions = totalElementsInRows - (eliminateStartElements + eliminateEndElements);
int halfElement = totalElementsPresentBetweenPositions/2;
int countElement = 0;
for(int i = iStart; i<= iEnd; i++) {
for(int j = 0; j< jMax; j++) {
countElement++;
if(halfElement == countElement) {
System.out.println("midd_i = "+ i +" and midd_j = "+j);
break;
}
}
}
}
I'm sure there should be an optimal solution, If anyone have the optimal solution, please help.
It's a wrong approach, please see the comment section below.
////////////////////////////
You can find the average between the points. When you have point A and point B. The program has to compute average in two dimensions: x=(Ax + Bx)/2. Similarly in the y-axis.
You don't have to worry about .5 appended to end of the number, because Java will truncate it for you.
There should be a way to do this with a geometric approach...
Find the midpoint between the two you want to get, so if you wanted to find the position between mat[0][0] and mat[2][2], you find the midpoints:
mid = (Math.abs(x1 - x2) / 2, Math.abs(y1 - y2) / 2)
x = (2 - 0) / 2 = 1
y = (2 - 0) / 2 = 1
so the answer there would be mat[1][1]
if it were a less straightforward example, such as mat[0][2] and mat[3][3]:
we first find the midpoint, such as:
x = (3 - 0) / 2 = 1.5
y = (3 - 2) / 2 = 0.5
round the answers to the nearest whole number to get the right indexes
You can simplify the task by imagining concrete numbers in the respective positions instead of the indices, which range from 0 to n x m - 1. Something like :
0, 1, 2, 3
4, 5, 6, 7
8, 9, 10, 11
12, 13, 14, 15
Then for each elemnt at m[i][j] applies
m[i][j] = i * m[i].length + j
and for each k, 0 <= k < n x m
i = k / m
j = k % m
which sums up in your method looking like:
static void getMiddle(int iStart, int jStart, int iEnd, int jEnd, int iMax, int jMax) {
int s = iStart * jMax + jStart;
int e = iEnd * jMax + jEnd;
int mid_i = ((e+s)/2)/jMax;
int mid_j = ((e+s)/2)%jMax;
System.out.println("midd_i = "+ mid_i +" and midd_j = "+mid_j);
}
Note: I'm not checking for valid inputs, for example if iStart <= iEnd <= iMax
Test out put with your input example:
getMiddle(0, 0, 2, 2, 4, 4);
getMiddle(0, 2, 2, 3, 4, 4);
getMiddle(1, 0, 3, 1, 4, 4);
midd_i = 1 and midd_j = 1
midd_i = 1 and midd_j = 2
midd_i = 2 and midd_j = 0
I wanna create a program that generates sets of consecutive numbers that add up to form a number. For example. if the input number is 15, it should give -
7, 8
4, 5, 6
1, 2, 3, 4, 5
Some formula/algorithm/loop that can do something that fits in. It could generate an array or print it. This may seem a math problem or silly question but I can't actually figure out how to do that programmatically in Java.
Please try to give exact code that can do the thing.
Say your input is N. You know each set of k consecutive numbers will be centered around N/k. A solution exists for even k if N/k ends with 0.5, and odd k if N/k is an integer. The solution, if one exists, is the k integers centered around N/k.
k=1: 15/1 = 15, so 15 (trivial; may want to omit)
k=2: 15/2 = 7.5, so 7,8
k=3: 15/3 = 5, so 4,5,6
k=4: 15/4 = 3.75, so no solution
k=5: 15/5 = 3, so 1,2,3,4,5
k=6: 15/6 = 2.5, so 0,1,2,3,4,5
etc...
k=15: 15/15 = 1, so -6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8
You can easily modify this to limit to positive or nonnegative solutions.
I'll expand on #MBo's answer as it conveys a very clean algorithm. Wiki provides a good intro on arithmetic progressions, copied below for your convenience.
Sum
Derivation
The sum of a sequence starting with number a and consisting of n consecutive numbers:
S = (n/2) * [2 * a + (n-1) * d]
For consecutive numbers the step d is 1.
S = (n/2) * [2 * a + (n-1)]
Here we can transition to #MBo's post.
P = 2 * S = n * [2 * a + (n-1)]
We can iterate all possible counts of consecutive numbers n and check if the resulting a is valid (i.e. a is an integer).
Let's factor out a.
Say P = n * q => q = 2 * a + (n-1) => 2 * a = q - n + 1 => a = (q - n + 1) / 2
Filters
1) we mentioned we could iterate all possible counts of consecutive numbers n, but given p = n * q it's safe to say n needs to be a divisor of p.
p % n == 0
nMax = (int)Math.sqrt(p)
2) a is an integer and a = (q - n + 1) / 2 => (q - n + 1) is even => q - n is odd.
((q - n) & 1) == 1
Implementation
import java.util.*;
import java.lang.Math;
import java.util.stream.IntStream;
import static java.util.stream.Collectors.toList;
public class Progressions
{
public static void main(String[] args)
{
List<List<Integer>> list = Calculate(15);
System.out.print(list);
}
public static List<List<Integer>> Calculate(int s)
{
List<List<Integer>> list = new ArrayList<>();
int p = 2*s;
int nMax = (int)Math.sqrt(p);
for (int n=2; n<=nMax; n++) {
if(p % n == 0) {
int q = p / n;
if(((q - n) & 1) == 1) {
int a = (q - n + 1) / 2;
list.add(range(a,n));
}
}
}
return list;
}
public static List<Integer> range(int a, int n) {
return IntStream.range(a, a+n)
.boxed()
.collect(toList());
}
}
Consecutive numbers form arithmetic progression. If it starts from number a and has n members, it's sum is
S = n * (2 * b + (n-1)) / 2
so
P = 2 * S = n * (2 * b + (n-1))
So for given input S we can factorize 2*S into all possible pairs of integer factors P = n * q where n<=q, then get starting number
a = (q - n + 1) / 2
If a is integer (oddity of q and n differs) then pair (a, n) represents valid sequence starting from a with n members
Example for S = 15, 2S = 30:
30 = 2 * 15 => n = 2, a = 7 => (7,8)
30 = 3 * 10 => n = 3, a = 4 => (4,5,6)
30 = 5 * 6 => n = 5, a = 1 => (1,2,3,4,5)
Simple Python example:
import math
def getseqs(s):
print(s)
p = 2 * s
for n in range(2, math.ceil(math.sqrt(p))):
if (p % n == 0):
q = p // n
if (((q - n) & 1) == 1): #compare parity
a = (q - n + 1) // 2
seq = list(range(a, a+n))
print(seq, sum(seq))
getseqs(17)
getseqs(15)
getseqs(72)
17
[8, 9] 17
15
[7, 8] 15
[4, 5, 6] 15
[1, 2, 3, 4, 5] 15
72
[23, 24, 25] 72
[4, 5, 6, 7, 8, 9, 10, 11, 12] 72
Consider the int input is your input number (ex. 15) and List<int[]> list as a storage of the result consecutive numbers, here you go:
List<int[]> list = new ArrayList<>();
int lower = 1; // Start searching from 1
int upper = (int) Math.floor(input + 1 / 2); // Up to the half of input (8+9 > 15)
while (lower < upper) { // Iterate between the bounds
int sum = 0;
for (int i = lower; i <= upper; i++) { // Iterate and sum the numbers
sum += i;
if (sum == input) { // If it matches the input
// Add the range to the List
// You have to loop them by one and add to the
// List before version Java-8
list.add(IntStream
.range(lower, i + 1)
.toArray());
break; // Found, no reason to continue
}
if (sum > input) { // Terminate the loop if the sum overlaps
break;
}
lower++; // Increment and try the sums from
// a higher starting number
sum = 0; // Reset the sum
}
The result for the input 15 is a List of these arrays:
[1, 2, 3, 4, 5]
[4, 5, 6]
[7, 8]
Here's a suggestion:
For an input number N:
you only have to consider numbers between 1 and N.
you can maintain an interval that represents the current subset of [1,...,N]. Maintain the sum of the current interval. The first interval will be [1,1], and its sum is 1.
As long as the sum < N, increase the right end of the interval by one (for example, you start with the interval [1,1]. Since 1 < N, you extend it to [1,2].
If the sum of the current interval is equal to N, you add that interval to the output, remove the left end of the interval (also removing it from the current sum), and continue.
If the sum exceeds N, you also remove the left end of the interval (also removing it from the current sum), and continue.
You finish when the interval becomes [N,N] (which is the final interval you should add to the output).
For the input 15, here's how the interval will change over time:
Interval Sum
[1] 1
[1,2] 3
[1,2,3] 6
[1,2,3,4] 10
[1,2,3,4,5] 15 -> output [1,2,3,4,5]
[2,3,4,5] 14
[2,3,4,5,6] 20
[3,4,5,6] 18
[4,5,6] 15 -> output [4,5,6]
[5,6] 11
[5,6,7] 18
[6,7] 13
[6,7,8] 21
[7,8] 15 -> output [7,8]
[8] 8
[8,9] 17
[9] 9
[9,10] 19
[10]
...
[15] 15 -> output 15
You can probably make some optimization once the sum of two consecutive numbers becomes higher than the target sum, at which point you can terminate the loop, and just add the final set (which contains just the target sum).
It used a Window Sliding Technique/Algorithm. You can also google sliding window algorithm sum.
I am writing Implementation of the #Dave solution.
Try to Solve before asking... That's how we learn. (only if we can't get then ask)
Scanner s = new Scanner(System.in);
int inputNumber = s.nextInt();
int k = 1;
while(inputNumber/k >= .5){
Float sequenceMid = (float) inputNumber/k;
if( k%2 == 0 && (sequenceMid *2 == Math.ceil(sequenceMid *2)) ){
for(int i = ((int)Math.floor(sequenceMid) - (k/2)),count=0 ; count < k ; count++,i++ ){
System.out.print(i + " ");
}
System.out.println();
}else if( (k%2 == 1) && (sequenceMid == Math.ceil(sequenceMid))){
for(int i = (Math.round(sequenceMid) - ((k-1)/2)),count=0 ; count < k ; count++,i++ ){
System.out.print(i + " ");
}
System.out.println();
}
k++;
}
Here is an idea that is similar to Eran's solution.
Since we're dealing with consecutive numbers, a cummulative sum (cumsum) can usually help. The basic idea is that we want to find the difference between two cummulative sums that gives exactly K, where K is 15 in your example.
number: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
cumsum: 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55
differences:
15 - 0 = 15 -> [1, 2, 3, 4]
21 - 6 = 15 -> [4, 5, 6]
36 - 21 = 15 -> [7, 8]
The cummulative sum starts from 0 so we can do 15 - 0 subtraction. The number included as the solution will be left-exclusive and right-inclusive. That just means add 1 to the left index (index starts from 0). Hopefully the pattern is quite clear.
The next task is to create an algorithm that does some sliding window with varying width across the cummulative sum. The idea is to search for the difference with the exact value of K. We can start at the beginning where the left and right side of the window points to 0. While the difference is <= K, we want to increase the right side of the window, enlarging the window and the difference.
number: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
cumsum: 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55
1st: (] -> 0 - 0 = 0
2nd: (---] -> 3 - 0 = 3
3rd: (------] -> 6 - 0 = 0
Once the algorithm hit 15, it will print out the first answer, and then it will increase it one more time. However, once we have the difference > K, we want to increase the left number, reducing the difference.
number: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
cumsum: 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55
1st: (-----------------] -> 15 - 0 = 15 <print>
2nd: (---------------------] -> 21 - 0 = 21
3rd: (-----------------] -> 21 - 1 = 20
Notice that the left side is bounded to be < K/2 since K//2 + (K//2 + 1) >= K (where the equality is possible due to integer division denoted by //). So we can stop the loop early when the left side reaches K//2 (due to left-exclusive).
public static int cumsum(int index) {
return index * (index + 1) / 2;
}
public static String printRange(int left, int right) {
StringBuilder buffer = new StringBuilder();
buffer.append('[');
for (int i=left+1;i<=right;i++) {
buffer.append(i);
buffer.append(',');
}
buffer.deleteCharAt(buffer.length()-1);
buffer.append(']');
return buffer.toString();
}
public static void main(String[] args) {
int K = 15;
int K_ov_2 = K/2;
int left_index = 0;
int right_index = 0;
int diff;
while (left_index < K_ov_2) {
diff = cumsum(right_index) - cumsum(left_index);
System.out.println("diff = " + diff + ", left = " + left_index + ", right = " + right_index);
if (diff == K) {
System.out.println(printRange(left_index,right_index));
}
if (diff <= K) {
right_index++;
} else {
left_index++;
}
}
}
I added the debug line so the output can become more obvious.
diff = 0, left = 0, right = 0
diff = 1, left = 0, right = 1
diff = 3, left = 0, right = 2
diff = 6, left = 0, right = 3
diff = 10, left = 0, right = 4
diff = 15, left = 0, right = 5
[1,2,3,4,5]
diff = 21, left = 0, right = 6
diff = 20, left = 1, right = 6
diff = 18, left = 2, right = 6
diff = 15, left = 3, right = 6
[4,5,6]
diff = 22, left = 3, right = 7
diff = 18, left = 4, right = 7
diff = 13, left = 5, right = 7
diff = 21, left = 5, right = 8
diff = 15, left = 6, right = 8
[7,8]
diff = 24, left = 6, right = 9
So this is a recent interview question, Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.
For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return
36 (10 = 3 + 3 + 4).
I'm trying to solve it recursively, The approach is
first split the number into two halves and find the max product and keep splitting each half till we get the maximum.
This is my code,
private int integerBreak(int n, int maxProduct){
int index = 0;
for(int i=0; i<n; i++){
if((i * (n-i)) >maxProduct) {
maxProduct = i*(n-i);
index = i;
}
}
return integerBreak(index, index) * integerBreak(n - index, n-index);
}
public int integerBreak(int n) {
int maxProduct = 0;
return integerBreak(n, maxProduct);
}
Now I'm a little lost with the base condition as to how to terminate recursion. I'd appreciate if someone can help me with my approach rather than coming up with the completely different solution.
I wrote a straightforward Java application to calculate the maximum product for the sum of integers of the numbers 2 through 20. The first number is the sum. The middle numbers are the factors of the sum. The final number is the product of the factors. Here are the results.
2 [1, 1] 1
3 [2, 1] 2
4 [2, 2] 4
5 [3, 2] 6
6 [3, 3] 9
7 [4, 3] 12
8 [3, 3, 2] 18
9 [3, 3, 3] 27
10 [4, 3, 3] 36
11 [3, 3, 3, 2] 54
12 [3, 3, 3, 3] 81
13 [4, 3, 3, 3] 108
14 [3, 3, 3, 3, 2] 162
15 [3, 3, 3, 3, 3] 243
16 [4, 3, 3, 3, 3] 324
17 [3, 3, 3, 3, 3, 2] 486
18 [3, 3, 3, 3, 3, 3] 729
19 [4, 3, 3, 3, 3, 3] 972
20 [3, 3, 3, 3, 3, 3, 2] 1458
The calculateMaximumFactors method calculates the factors with the maximum product. The factor method generates the factors of the sum. The product method calculates the product of the factors. Here's the code:
package com.ggl.testing;
import java.util.Arrays;
public class MaximumProduct {
public static void main(String[] args) {
for (int sum = 2; sum <= 20; sum++) {
System.out.print(sum + " ");
System.out.println(calculateMaximumFactors(sum));
}
}
private static String calculateMaximumFactors(int sum) {
int[] previousFactors = new int[0];
int maxProduct = 0;
for (int i = 2; i <= sum; i++) {
int[] factors = factor(sum, i);
int product = product(factors);
if (product > maxProduct) {
maxProduct = product;
previousFactors = Arrays.copyOf(factors, factors.length);
}
}
return Arrays.toString(previousFactors) + " " + maxProduct;
}
private static int[] factor(int sum, int divisor) {
if (sum < divisor) {
return new int[0];
}
int num = sum / divisor;
int remainder = sum % divisor;
int[] result = new int[divisor];
for (int i = 0; i < divisor; i++) {
result[i] = num;
if (remainder > 0) {
result[i]++;
remainder--;
}
}
return result;
}
private static int product(int[] factors) {
int product = 1;
for (int i = 0; i < factors.length; i++) {
product *= factors[i];
}
return product;
}
}
Here's my solution to the problem : (Idea : It is optimal to break integer into multiple of 3)
public int integerBreak(int n) {
// base case :
if (n == 2 || n == 3){
return (n-1);
}
int maxProduct = 1;
while (n > 4){
n -= 3;
maxProduct *= 3; // Keep multiplying 3.
}
return (n * maxProduct); // multiply with left over n.
}
This is simple O(N) solution. Hope this helps someone !
The idea is to break the number into multiples of 2 or 3. If you write the breaking results for couple of numbers like 7 to 10 you should get the idea. Assuming the max number is 60, there is a simple dynamic solution:
int dp[60];
public:
int integerBreak(int n)
{
dp[1]=1,dp[2]=1,dp[3]=2,dp[4]=4,dp[5]=6,dp[6]=9;
for(int i=7;i<=n;i++)
dp[i]=max(dp[i-3]*3,dp[i-2]*2);
return dp[n];
}
};
As I wrote in the comment above, we have to break the number into 3s. If we derive the maxima, we get the e (base of the logarithm) to be 2 < e < 3. But the thing is 6= 33 and 6=22*2 so every triplet of 2 can be replaced with a tuple of 3 for the maximum product.
So here is the code I wrote. It is in Python so I hope you don't mind -
def maximize_product(num):
product = 1
if num == 2 or num == 3:
return num - 1
else:
while num > 4:
product = product * 3
num -= 3
return num * product
If you make a loop trying to find the number then is going to get complicated and not as efficient (the greater the number, the longest will take you to find it, you need to consider indexes, etc etc)
The best and fastest algorithm is the middle point algorithm, i.e divide the given number by 2, calculate deviation if number is odd, finally calculate the product
Example:
static int func(int number) {
int result = 0;
if (number < 0) {
System.err.println("no negative allowed");
System.exit(0);
}
int a = 0;
int b = 0;
a = number / 2;
b = number / 2;
a += number - (a + b);
result = a * b;
System.out.println(" this is a " + a);
System.out.println(" this is b " + b);
return result;
}
if you execute it like
public static void main(String[] args) {
int number = 9;
int result = func(number);
System.out.println(result);
}
will get the results correctly...
How would I write the following for loop using an enhanced for loop>
int [] info = {1,2,3,4,5,6,7,8,9,10};
int i;
for (i = 0; i < info.length; i++) {
if ((i+1) % 10 == 0)
System.out.println(info[i]);
else
System.out.println(info[i] + ", ");
}
I am trying the following, but i guess im doing it incorreclty
for(int i: info){
body here///
Your syntax is correct. The difference is only that you're assigning the actual int value to i instead of the loop index. Thus, if you replace (i+1) % 10 by i % 10 and info[i] by i, it will work correctly.
int[] info = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i : info) {
if (i % 10 == 0)
System.out.println(i);
else
System.out.println(i + ", ");
}
To learn more about the enhanced for loop, check this Sun guide.
The above can by the way be shortened with help of the ternary operator ;)
int[] info = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i : info) {
System.out.println(i + (i % 10 == 0 ? "" : ", "));
}