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.
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
---------------------------------------
I am trying to generate a power set (all possible subsets) of integers based on a given set of integers. I am trying to use recursion based on the principle that each element in the master set can be in a subset or not in a subset. However, when I run my function on the example set {1, 5, 11, 5}, I am missing subsets, such as {1, 5, 5}. Below is my Java code:
// Function to generate power set of given set S
public static void determinePowerSet(int[] baseSet, List<Integer> currSet, int index, int sum)
{
// If the current index is at the end, we've finished generating subsets
if (index == baseSet.length) {
return;
}
// The subset in which we add the current element in the list
List<Integer> addToSet = new LinkedList<Integer>(currSet);
addToSet.add(baseSet[index]);
// Do not add the current element to the set
determinePowerSet(baseSet, currSet, index + 1, sum);
// Add the current element to the set
determinePowerSet(baseSet, addToSet, index + 1, sum + baseSet[index]);
}
public static void main(String[] args)
{
determinePowerSet(new int[] {1, 5, 11, 5}, new LinkedList<Integer>(), 0, 0);
}
Below is the output of the function call:
sum = 0, currSet = [], index = 0
sum = 0, currSet = [], index = 1
sum = 0, currSet = [], index = 2
sum = 0, currSet = [], index = 3
sum = 11, currSet = [11], index = 3
sum = 5, currSet = [5], index = 2
sum = 5, currSet = [5], index = 3
sum = 16, currSet = [5, 11], index = 3
sum = 1, currSet = [1], index = 1
sum = 1, currSet = [1], index = 2
sum = 1, currSet = [1], index = 3
sum = 12, currSet = [1, 11], index = 3
sum = 6, currSet = [1, 5], index = 2
sum = 6, currSet = [1, 5], index = 3
sum = 17, currSet = [1, 5, 11], index = 3
Everything is fine in your code. Let's take a look:
class Solution{
// Function to generate power set of given set S
public static void determinePowerSet(int[] baseSet, List<Integer> currSet, int index, int sum)
{
// If the current index is at the end, we've finished generating subsets
if (index == baseSet.length) {
for(int i : currSet)
System.out.print(i+" ");
System.out.println();
return;
}
// The subset in which we add the current element in the list
List<Integer> addToSet = new LinkedList<Integer>(currSet);
addToSet.add(baseSet[index]);
// Do not add the current element to the set
determinePowerSet(baseSet, currSet, index + 1, sum);
// Add the current element to the set
determinePowerSet(baseSet, addToSet, index + 1, sum + baseSet[index]);
}
public static void main(String[] args)
{
determinePowerSet(new int[] {1, 5, 11, 5}, new LinkedList<Integer>(), 0, 0);
}
}
OUTPUT:
5
11
11 5
5
5 5
5 11
5 11 5
1
1 5
1 11
1 11 5
1 5
1 5 5
1 5 11
1 5 11 5
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");
}
}
The program is supposed to shift all values in the array to the right. Please help with what I have done wrong...
int[] array = new int[] {1, 2, 3, 4, 5};
int[] rotated = new int [array.length];
int rotationTimes = scan.nextInt();
if (rotationTimes > 4){
rotationTimes %= 5;
}
for (int i = 0; i <= rotationTimes; i++){
if (i == 4) {
rotated[0] = array[4];
break;
}
array[i] = rotated[i + 1];
}
System.out.println(Arrays.toString(rotated));
The expected output should be {5, 1, 2, 3, 4}. It outputs an array of 0s...
Thank you a lot.
You weren't populating the rotated array. You were modifying the array reference!
You were checking if index == 4 when you could do array.length - 1.
You need to determine the target index as being (index + rotationTimes) then if it exceeds array.length - 1 (the last index) you use the modulus operator to make sure it doesnt overflow. For example, if the current index is 4 (the last one) and the iterations is 1, (4 + 1) is greater than 4 so the target index is (4 + 1) % 5 = 0.
public static void main(String[] args) {
int[] array = new int[] {1, 2, 3, 4, 5};
int[] rotated = new int [array.length];
System.out.println("Enter amount of times to rotate: ");
Scanner scan = new Scanner(System.in);
int rotationTimes = scan.nextInt();
if (rotationTimes > 4){
rotationTimes %= 5;
}
for (int index = 0; index < array.length; index++) {
int targetIndex = index + rotationTimes;
if (targetIndex > array.length - 1) {
targetIndex %= array.length;
}
rotated[targetIndex] = array[index];
}
System.out.println("Input: " + Arrays.toString(array));
System.out.println("Rotations: " + rotationTimes);
System.out.println("Output: " + Arrays.toString(rotated));
}
Input: [1, 2, 3, 4, 5]
Rotations: 1
Output: [5, 1, 2, 3, 4]
Input: [1, 2, 3, 4, 5]
Rotations: 2
Output: [4, 5, 1, 2, 3]