Related
I have an array like this one-
{1, 2, 3, 4, 5, 6}
I want to sort it in the order of multiples of 3 with remainders 0, 1 and 2. (the first group is multiples of 3, the second one is multiples of 3 with remainder 1 and the last one is multiples of 3 with remainder 2) and I want to preserve the order in which elements appear in the array.
The result should be -
{3, 6, 1, 4, 2, 5}
I have this code-
int current = 0;
int b = 0;
for (int i = 0; i < 3; i++) { //3 groups
for (int j = current; j < numbers.length; j++) {
if (numbers[j] % 3 == i) { //reminder should be 0,1 or 2
b = numbers[j];
numbers[j] = numbers[current];
numbers[current] = b;
current++;
}
}
}
But this code does not preserve the order in which elements appear in the array. The result I got is-
{3, 6, 1, 4, 5, 2}
But I want the result to be like {3, 6, 1, 4, 2, 5}. How can I achieve this?
Using stream and comparator
int[] array = {1, 2, 3, 4, 5, 6};
List<Integer> lst = Arrays.stream(array)
.boxed()
.sorted(Comparator.comparingInt(o -> o % 3))
.collect(Collectors.toList());
System.out.println(lst);
In your solution you are swapping the elements in place, which shuffles them from the initial order. That's why you don't have the same ordering at the end. I'm not sure if there is another way apart from having a second array to keep the sorted elements, while at the same time iterating over the original one like so:
public static void main(String[] args) {
int[] numbers = new int[]{1, 2, 3, 4, 5, 6};
int[] result = new int[numbers.length];
int b = 0;
int current = 0;
for (int i = 0; i < 3; i++) { //3 groups
for (int j = 0; j < numbers.length; j++) {
if (numbers[j] % 3 == i) { //reminder should be 0,1 or 2
result[current] = numbers[j];
current++;
}
}
}
System.out.println(Arrays.toString(result));
}
Output: [3, 6, 1, 4, 2, 5]
You can use an IntStream and a Comparator to sort the stream:
int[] arr = {1, 2, 3, 4, 5, 6};
int[] arrSorted = IntStream.of(arr).boxed()
.sorted(Comparator.comparingInt(i -> i % 3))
.mapToInt(Integer::intValue)
.toArray();
System.out.println(Arrays.toString(arrSorted));
Output:
[3, 6, 1, 4, 2, 5]
Note: From IntStream.of() javadoc:
Returns a sequential ordered stream whose elements are the specified
values.
I would create a new array of the same size and then place the elements in the correct order. For example like this:
int[] array = {1, 2, 3, 4, 5, 6};
int[] sorted = new int[array.length];
int counter = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] % 3 == i) {
sorted[counter] = array[j];
counter++;
}
}
}
System.out.println(Arrays.toString(sorted));
Output:
[3, 6, 1, 4, 2, 5]
Alternatively, you can use Java 8 features to reduce the amount of code like this:
int[] array = {1, 2, 3, 4, 5, 6};
int[] sorted = Arrays.stream(array).boxed().sorted(Comparator.comparingInt(a -> (a % 3))).mapToInt(i -> i).toArray();
Output:
[3, 6, 1, 4, 2, 5]
Here is a full program description with test cases and below it is my solution:
Given an array of integers int A[], find the length and location of the longest contiguous sequence of equal values for which the values of the elements just before and just after this sequence are smaller.
You should just print these two numbers (first is the length and second is the starting index of the plateau).
To complete the definition, we can consider there are imaginary index positions at A[-1] and A[A.length] where A[-1] < A[0] and A[A.length] < A[A.length-1]. Therefore, the plateau can start/end at both ends of array A. This condition guarantees the existence of a plateau. A plateau can be of length 1.
Example 1:
java LongestPlateau 1 2 2 2 2 1
With these command-line arguments, the program should print:
4
1
Example 2:
java LongestPlateau 1 2 2 2 2 3
With these command-line arguments, the program should print:
1
5
Example 3:
java LongestPlateau 3 2 2 2 1 2 1 1 1 2 2 0 1 1 1 1 0
With these command-line arguments, the program should print:
4
12
Here is my Solution:
public class LongestPlateau {
private static int[] parseInputArray(String[] args) {
int[] value = new int[args.length+1];
for(int i = 0 ; i < args.length; i++){
if (i == args.length-1) value[i] = 0; // this imaginary last value of the array ensures that if the plateau is the last value of the array, then it outputs the correct answer
value[i] = Integer.parseInt(args[i]);
}
return value;
}
public static void printLargestPlateau(int[] values) {
int biggestStartIndex = -1;
int biggestLength = 0;
int currentIndex = 1;
int currentPlateauStartIndex = 1;
int currentLength = 1;
boolean plateauStarted = false;
while (currentIndex < values.length) {
if(isStartOfPlateau(currentIndex, values)){
currentLength = 1;
plateauStarted = true;
currentPlateauStartIndex = currentIndex;
} else if (isEndOfPlateau(currentIndex, values)) {
if(plateauStarted && currentLength > biggestLength){
biggestLength = currentLength;
biggestStartIndex = currentPlateauStartIndex;
}
plateauStarted = false;
currentLength = 1;
} else {
currentLength++;
}
currentIndex++;
}
System.out.println(biggestLength +"\n"+biggestStartIndex);
}
private static boolean isStartOfPlateau(int index, int[] values){
if(index <= 0){
return false;
}
return values[index-1] < values[index];
}
private static boolean isEndOfPlateau(int index, int[] values){
if(index <= 0){
return false;
}
return values[index - 1] > values[index];
}
public static void main(String[] args) {
int[] values = parseInputArray(args);
printLargestPlateau(values);
}
}
As I mentioned in the comments, existing code fails to detect plateaus at the start and the end of the input data, and the following implementation fixes this issue.
static void printLargestPlateau(int ... arr) {
int start = -1, maxStart = -1;
int length = 0, maxLength = -1;
boolean onPlateau = false;
if (arr.length > 0) {
start = 0;
length = 1;
onPlateau = true;
for (int i = 1; i < arr.length; i++) {
if (arr[i] == arr[i - 1]) {
if (onPlateau) {
length++;
}
} else if (arr[i] < arr[i - 1]) {
if (length > maxLength) {
maxLength = length;
maxStart = start;
}
onPlateau = false;
} else { // possible start of new plateau
onPlateau = true;
start = i;
length = 1;
}
}
// check possible plateau at the end
if (length > maxLength) {
maxLength = length;
maxStart = start;
}
}
System.out.println(maxLength);
System.out.println(maxStart);
}
Tests:
int[][] tests = {
{},
{1},
{1, 1},
{1, 2},
{1, 1, 2},
{1, 2, 2},
{1, 2, 1},
{1, 2, 3},
{1, 2, 2, 2, 3, 3, 1, 1, 1, 1},
{1, 2, 2, 2, 2, 1},
{1, 2, 2, 2, 2, 3},
{3, 2, 2, 2, 1, 2, 1, 1, 1, 2, 2, 0, 1, 1, 1, 1, 0},
{3, 3, 3, 3, 1, 1, 0, 2, 2, 2, 2, 2, 2}
};
for (int[] arr : tests) {
System.out.println(Arrays.toString(arr));
printLargestPlateau(arr);
System.out.println("-".repeat(arr.length * 3));
}
Output:
[]
-1
-1
[1]
1
0
---
[1, 1]
2
0
------
[1, 2]
1
1
------
[1, 1, 2]
1
2
---------
[1, 2, 2]
2
1
---------
[1, 2, 1]
1
1
---------
[1, 2, 3]
1
2
---------
[1, 2, 2, 2, 3, 3, 1, 1, 1, 1]
2
4
------------------------------
[1, 2, 2, 2, 2, 1]
4
1
------------------
[1, 2, 2, 2, 2, 3]
1
5
------------------
[3, 2, 2, 2, 1, 2, 1, 1, 1, 2, 2, 0, 1, 1, 1, 1, 0]
4
12
---------------------------------------------------
[3, 3, 3, 3, 1, 1, 0, 2, 2, 2, 2, 2, 2]
6
7
---------------------------------------
hello to all you code geniuses on here
ill try to explain my problem as simply as i can
image1
To produce image1, lets say an array like below is required, keeping in mind that the numbers are placed left to right in the first row, then go backwards in the second row, and if you added more numbers, it would create a third row.
int[] something = {1, 2, 3, 2, 1, 2, 1, 3, 3, 1, 1, 2}
so i want to make to make a "map" of the layout, like this desired output below.
2 1 1 3 3 1
1 2 3 2 1 2
and then from there i would want to find the total for each column, so like this.
2 1 1 3 3 1
1 2 3 2 1 2
..................
3 3 4 5 4 3
(and i then want to make store this layout and sum within another array)
hopefully that all made sense, if so,
how could i go about doing this?
thanks heaps : )
Seems like you can use a two-dimensional array data structure to solve this:
int[][] something = new int[][]{
{2, 1, 1, 3, 3, 1},
{1, 2, 3, 2, 1, 2}
};
int totalForColomn1 = something[0][0] + something [1][0];
int totalForColomn2 = something[0][1] + something [1][1];
// ...
int totoalForColomn6 = something[0][5] + something [1][5];
If you could only use one-dimensional array:
int[] something = new int[] {2, 1, 1, 3, 3, 1, 4, 2, 3, 2, 1, 2};
int row_size = 6;
int totalForColomn1 = something[0] + something[0 + row_size];
int totalForColomn2 = something[1] + something[1 + row_size];
// ...
int totalForColomn6 = something[5] + something[5 + row_size];
Remember to keep a consistant row_size by putting those undecided element to 0.
In this case, you should init your array like:
int[] something = new int[] {0, 0, 0, 0, 1, 4, 1, 2, 3, 2, 1, 1};
So If I am reading this correctly if L is the length of your array you want to add the nth and L-1-nth element of the array and store the result in an array. I through this together quickly so I did not handle what happens if the input array is of odd length (your question did not specify).
import java.util.Arrays;
public class App {
public static void main(String[] args) {
int[] something = {1, 2, 3, 2, 1, 2, 1, 3, 3, 1, 1, 2};
System.out.println(Arrays.toString(addValues(something)));
}
public static int [] addValues(int [] input){
int[] output = new int[input.length / 2];
for(int i = 0; i<input.length/2; i++){
output[i] = input[i] + input[input.length -1 - i ];
}
return output;
}
}
EDIT:
I think this will work for the case where the are an arbitrary number of rows.
The main insite into how this work is in the grid below.
0 1 2 3 4 5 :row 0
11 10 9 8 7 6 :row 1
12 13 14 15 16 17:row 2
23 22 21 20 19 18:row 3
So whether the output index is going up or down is determined by the row number and every time we hit an input index that is the same size as our output array we need to stay at the same output index.
import java.util.Arrays;
public class App {
public static void main(String[] args) {
int[] something = { 1, 2, 3, 2, 1, 2, 1, 3, 3, 1, 1, 2 };
System.out.println(Arrays.toString(addValues(something, 6)));
}
public static int[] addValues(int[] input, int row_lenth) {
int[] output = new int[row_lenth];
int output_index = 0;
for (int i = 0; i < input.length; i++) {
if (i % row_lenth != 0) {
if ((i / row_lenth) % 2 == 0) {
output_index++;
} else {
output_index--;
}
}
output[output_index] += input[i];
}
return output;
}
}
import java.util.Scanner;
public class Stckoverq {
public static void main(String args[]) {
Scanner sn = new Scanner(System.in);
System.out.print("What is the size of array? ");
int size = sn.nextInt();
System.out.print("What is length of the row?");
int len = sn.nextInt();
int ind = 0, i = 0, j = 0;
//variable 'ind' is for getting the element from arr[] array at index ind
int rac[][] = new int[size/len][len];
//variable 'i' and 'j' is for storing rows and column elements respectively in array rac[]
int arr[] = new int[size];
System.out.println("Enter array elements: ");
for(int k=0;k<size;k++)
arr[k] = sn.nextInt();
while(ind!=arr.length)
{
if(j==len) {
j=0; //Reset column index
i++; //Increase row index
}
rac[i][j] = arr[ind];
ind++;
j++; //Increase column index
}
//Now print the rows and columns................
for(int r =0;r<size/len;r++) {
for(int c=0;c<len;c++)
System.out.print(rac[r][c]+"\t");
System.out.println();
}
int sum[] = new int[len];
//this array sum[] is used to store sum of all row elements.
int s = 0;
for(int c=0;c<len;c++) {
for(int r =0;r<size/len;r++)
s += rac[r][c];
sum[c] = s;
s = 0;
}
for(int x: sum)
System.out.print(x+"\t");
}
}
I want to make a function that takes as parameters an array and a boolean. The boolean tells the function if the rest of the division of the array is to be included. It then returns a new array which is the copy of the second half of the first:
secondHalf({1, 2, 3, 4, 5}, true) → {3, 4, 5}
secondHalf({1, 2, 3, 4, 5}, false) → {4, 5}
For this assignment, I'm not supposed to use any other classes.
Here's what I've attempted:
static int[] secondHalf(int[] vector, boolean include) {
int size = vector.length/2;
if(vector.length%2 == 0)
include = false;
if(include)
size ++;
int[] vector_2 = new int[size];
int i = 0;
while(i < size){
if(include)
vector_2[i] = vector[i+size-1];
vector_2[i] = vector[i+size+1];
i++;
}
return vector_2;
To find the size of vector_2, I've decided to use compound assignment operators. So the first part of this solution checks for the required condition and assigns a value to size in a single statement.
Since we know how many times to iterate over the loop, I think a for loop would be more appropriate than a while loop.
The loop retrieves all the values in vector from the middle of the array to the end of the array and places each value into vector_2.
static int[] secondHalf(int[] vector, boolean include) {
int size = vector.length/2 + (include && vector.length%2 != 0 ? 1 : 0);
int[] vector_2 = new int[size];
for(int i = 0; i < size; i++)
vector_2[i] = vector[vector.length - size + i];
return vector_2;
}
People have hinted at System#arraycopy, but with Arrays.copyOfRange there is an even simpler method, where you only have to define the proper start index and directly receive the copy.
The start index is array.length / 2 by default. Iff the include flag is true, then you have to add the remainder of dividing the array length by 2 to that.
An MCVE:
import java.util.Arrays;
public class ArrayPartCopy
{
public static void main(String[] args)
{
int array0[] = { 1, 2, 3, 4, 5 };
System.out.println("For " + Arrays.toString(array0));
System.out.println(Arrays.toString(secondHalf(array0, true)));
System.out.println(Arrays.toString(secondHalf(array0, false)));
int array1[] = { 1, 2, 3, 4 };
System.out.println("For " + Arrays.toString(array1));
System.out.println(Arrays.toString(secondHalf(array1, true)));
System.out.println(Arrays.toString(secondHalf(array1, false)));
}
static int[] secondHalf(int[] array, boolean include)
{
int start = array.length / 2;
if (include)
{
start += array.length % 2;
}
return Arrays.copyOfRange(array, start, array.length);
}
}
The output is
For [1, 2, 3, 4, 5]
[4, 5]
[3, 4, 5]
For [1, 2, 3, 4]
[3, 4]
[3, 4]
I have an array of integers like this one
int [] num = {5, 8, 1, 1, 2, 3, 2}
and I want to divide it into 2 parts, so that the total of 2 sets will be as equal as possible: (output)
SET 1: 5 Piece(s)
1
1
2
2
5
Total: 11
SET 2: 2 Piece(s)
8
3
Total: 11
another example is
int [] num = {4, 6, 1, 2, 3, 3, 4}
with output like this:
SET 1: 3 Piece(s)
3
4
4
Total: 11
SET 2: 4 Piece(s)
6
1
2
3
Total: 12
any help? =) thanks
If the array is not too long, try a lazy solution: brute-force. Since all you need is to separate it into two sets, you'll need to check 2^n possibilities, because a number is either in the first set or not (i.e. in the second set).
Here's a sample code I just wrote:
public static int[][] bruteForce(int[] input) {
int n = input.length;
int[][] res = new int[2][n];
int minVal = Integer.MAX_VALUE;
int iMinVal = 0;
int limit = (int) Math.pow(2, n);
for (int i = 0; i < limit; i++) {
int v = i;
int diff = 0;
for (int j = 0; j < n; j++) {
diff = diff + ((v & 1) == 0 ? +1 : -1) * input[j];
v = v >> 1;
}
if (Math.abs(diff) < minVal) {
iMinVal = i;
minVal = Math.abs(diff);
}
}
int a = 0, b = 0;
for (int i = 0; i < n; i++) {
if ((iMinVal & 1) == 0) {
res[0][a++] = input[i];
} else {
res[1][b++] = input[i];
}
iMinVal = iMinVal >> 1;
}
return res;
}
public static void main(String[] args) {
int[] num = {5 ,8 ,1 ,1 ,2 ,3 ,2};
int[] num2 = {4, 6, 1, 2, 3, 3, 4};
int[][] r = bruteForce(num);
System.out.println("First example:");
System.out.println(Arrays.toString(r[0])+ ", sum = "+Arrays.stream(r[0]).sum());
System.out.println(Arrays.toString(r[1])+ ", sum = "+Arrays.stream(r[1]).sum());
r = bruteForce(num2);
System.out.println("Second example:");
System.out.println(Arrays.toString(r[0])+ ", sum = "+Arrays.stream(r[0]).sum());
System.out.println(Arrays.toString(r[1])+ ", sum = "+Arrays.stream(r[1]).sum());
}
output:
First example:
[5, 1, 3, 2, 0, 0, 0], sum = 11
[8, 1, 2, 0, 0, 0, 0], sum = 11
Second example:
[2, 3, 3, 4, 0, 0, 0], sum = 12
[4, 6, 1, 0, 0, 0, 0], sum = 11
If the length of the array is big, then I guess try some smart brute-force, or other methods. Like, sorting the array into non-ascending order, then starting from the biggest value, put each value into the array with less sum, which in the current case give the right answer:
public static int[][] alternative(int[] input) {
int n = input.length;
int[][] res = new int[2][n];
int[] input0 = Arrays.copyOf(input, n);
Arrays.sort(input0);
System.out.println("Input: "+Arrays.toString(input)+", ordered: "+Arrays.toString(input0));
int sum1 = 0, sum2 = 0;
int a = 0, b = 0;
for (int i = n-1; i >= 0; i--) {
if (sum1 <= sum2) {
res[0][a++] = input0[i];
sum1 = sum1 + input0[i];
System.out.println("Adding "+input0[i]+" into set 1 ==> Sum1 = "+sum1);
} else {
res[1][b++] = input0[i];
sum2 = sum2 + input0[i];
System.out.println("Adding "+input0[i]+" into set 2 ==> Sum2 = "+sum2);
}
}
return res;
}
output:
First example:
Input: [5, 8, 1, 1, 2, 3, 2], ordered: [1, 1, 2, 2, 3, 5, 8]
Adding 8 into set 1 ==> Sum1 = 8
Adding 5 into set 2 ==> Sum2 = 5
Adding 3 into set 2 ==> Sum2 = 8
Adding 2 into set 1 ==> Sum1 = 10
Adding 2 into set 2 ==> Sum2 = 10
Adding 1 into set 1 ==> Sum1 = 11
Adding 1 into set 2 ==> Sum2 = 11
[8, 2, 1, 0, 0, 0, 0], sum = 11
[5, 3, 2, 1, 0, 0, 0], sum = 11
Second example:
Input: [4, 6, 1, 2, 3, 3, 4], ordered: [1, 2, 3, 3, 4, 4, 6]
Adding 6 into set 1 ==> Sum1 = 6
Adding 4 into set 2 ==> Sum2 = 4
Adding 4 into set 2 ==> Sum2 = 8
Adding 3 into set 1 ==> Sum1 = 9
Adding 3 into set 2 ==> Sum2 = 11
Adding 2 into set 1 ==> Sum1 = 11
Adding 1 into set 1 ==> Sum1 = 12
[6, 3, 2, 1, 0, 0, 0], sum = 12
[4, 4, 3, 0, 0, 0, 0], sum = 11
For the 0s in the output, you can just write a simple function that create a new arrays without the 0s.
Have a for loop to loop like:
int sum =0:
for(int I=0; I<num.length/2; I++){
System.out.println(num[i]);
sum=sum+num[i];
}
System.out.println(sum);
(Written on ipad excuse any mistakes plz.
We should try with all combinations. For example, if the array is (1,1,100,100), then answer is (100,1) (100,1). If the array is (1,1,50,100) then answer is (1,1,50) (100). I don't think there is any short cut to this. If the array has N elements, then we shall try all combinations (Nc1, NcN01), (Nc2, NcN-2) .. and so on. Then find which of their difference is least.