Sum of all elements of each subarray - java

I was solving Kadane's algorithm , a very weird approach came to my mind while solving it. What if we find a way to find out the sum of all the elements of all possible subarrays forming from an array and store it in an arraylist. I've been thinking about it for a long time now, but I'm unable to solve it. It would be great if I can get some assistance.
`
import java.util.*;
import java.lang.*;
import java.io.*;
class Sample
{
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for(int i=0;i<n;i++){
arr[i]=sc.nextInt();
}
ArrayList<Integer> list = new ArrayList<>();
int sum=0;
for(int i=0;i<n;i++){
sum+=arr[i];
}
list.add(sum);
for(int i=0;i<n;i++){
list.add(arr[i]);
}
for(int i=0;i<n;i++){
//sum-=arr[i];
if(!list.contains(sum-arr[i]) && (sum-arr[i])>0){
list.add(sum-arr[i]);
}
sum=sum-arr[i];
}
System.out.println(list);
}
}
`
This is what I've done till now. There's a very big flaw in the logic and I know it but I just can't seem to solve it.

This doesn't use Kadanes algorithm, but it does sum the sub arrays. It is facilitated by using the subList method of the List interface.
for (int i = 1; i < 8; i++) {
List<Integer> list =
IntStream.range(1, i+1).boxed().toList();
List<Integer> sums = new ArrayList<>();
findsubs(list, 0, list.size(), sums);
System.out.println(sums);
sums.clear();
}
prints
[1]
[3, 2, 1]
[6, 5, 3, 3, 2, 1]
[10, 9, 7, 4, 6, 5, 3, 3, 2, 1]
[15, 14, 12, 9, 5, 10, 9, 7, 4, 6, 5, 3, 3, 2, 1]
[21, 20, 18, 15, 11, 6, 15, 14, 12, 9, 5, 10, 9, 7, 4, 6, 5, 3, 3, 2, 1]
[28, 27, 25, 22, 18, 13, 7, 21, 20, 18, 15, 11, 6, 15, 14, 12, 9, 5, 10, 9, 7, 4, 6, 5, 3, 3, 2, 1]
The method
public static void findsubs(List<Integer> list, int s, int e,
List<Integer> sums) {
if (s >= e) {
return;
}
for (int i = s; i < e; i++) {
sums.add(list.subList(i, e).stream()
.mapToInt(Integer::intValue).sum());
}
findsubs(list, s, e - 1, sums);
}

long subarraySum(vector<long> &A) {
long result = 0;
int n = A.size();
for (int i=0; i <n; ++i)
{
result +=(A[i]*(i+1)*(n-i));
}
return result;
}
Sum of all sub array means,
Actually each element how many time contribute himself in each sub array
lets take : [1 2 3 4][0,0][0,1][1,1][0,2][1,2][2,2][0,3][1,3][2,3][3,3]
contribution of ith element is A[i](i+1)(n-i)

Related

How could we split an array into two new ones which their weight differences are minimal? [duplicate]

This question already has answers here:
Minimum sum partition of an array
(3 answers)
Closed 2 years ago.
I am doing the following programming exercise: Stone pile. The statement is:
You are given pile of stones with different weights.
Your task is to divide this stone pile into two parts, so the weight
difference between the piles will be minimal. You can't break one
stone into smaller ones.
For example if we have stones:
[1, 2, 3, 4]
We could divide them into:
[2, 3], [1, 4]
So the difference will be 0
If you are given empty stone pile, you can still divide it into two
piles with no stones.
The pile will contain maximum 22 stones. 🗿
Following the examples I have thought:
Sort stones in ascending order
for each stone
if length is even
if movement is even
add min and max to right list
remove them
if movement is odd
add min and max to left list
remove them
if length is odd
if movement is even
add max to left
remove it
if movement is odd
add min to right
remove it
if there are more items
add next min
remove it
So in code would be:
import java.util.*;
import java.util.stream.*;
public class Pile {
public static int minDiff(int[] stones) {
System.out.println("stones: "+Arrays.toString(stones));
Arrays.sort(stones);
System.out.println("stones: "+Arrays.toString(stones));
List<Integer> allStones = Arrays.stream(stones).boxed().collect(Collectors.toList());
System.out.println("allStones: "+Arrays.toString(allStones.toArray()));
ArrayList<Integer> left = new ArrayList<>();
ArrayList<Integer> right = new ArrayList<>();
for(int i = 0; allStones.size()>0; i++){
if(stones.length%2==0){
if(i%2==0){
right.add(allStones.get(0));
right.add(allStones.get(allStones.size()-1));
allStones.remove(0);
allStones.remove(allStones.size()-1);
}else{
left.add(allStones.get(0));
left.add(allStones.get(allStones.size()-1));
allStones.remove(0);
allStones.remove(allStones.size()-1);
}
}else{
if(i%2==0){
left.add(allStones.get(allStones.size()-1));
allStones.remove(allStones.size()-1);
}else{
right.add(allStones.get(0));
allStones.remove(0);
if(allStones.size()>0){
right.add(allStones.get(0));
allStones.remove(0);
}
}
}
}
System.out.println("left: "+Arrays.toString(left.toArray()));
System.out.println("right: "+Arrays.toString(right.toArray()));
return left.stream().mapToInt(Integer::intValue).sum()-right.stream().mapToInt(Integer::intValue).sum();
}
}
Currently it is just working when we test it with inputs where the difference is zero. However if we test it with other inputs, it will fail.
Given the following tests, the first suite will pass, the others fail:
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;
public class PersonTest {
#Test
public void testDifferenceShouldBeZero(){
assertEquals(0, Pile.minDiff(new int[]{1, 2, 3}));
assertEquals(0, Pile.minDiff(new int[]{1, 2, 3, 4}));
assertEquals(0, Pile.minDiff(new int[]{5,5,4,3,3}));
}
#Test
public void testDifferenceShouldBeOne(){
assertEquals(1, Pile.minDiff(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}));
}
#Test
public void testDifferenceShouldBeTwo(){
assertEquals(2, Pile.minDiff(new int[]{89409, 34351, 3065, 10128, 27694, 27585, 87350, 33875, 2658, 41606, 57512, 73368, 83345, 37048, 31827, 94644, 15972, 74813, 31441, 70395}));
}
}
For example, when stones are: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
Trace is:
stones: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
stones: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
allStones: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
left: [2, 21, 4, 19, 6, 17, 8, 15, 10, 13]
right: [1, 22, 3, 20, 5, 18, 7, 16, 9, 14, 11, 12]
Being the result:
expected:<1> but was:<-23>
How could we split the stone pile in two chunks where the difference is the minimum, for the general case?
We have read:
Make copy of an array
How to convert int[] into List<Integer> in Java?
How to get the last value of an ArrayList
Is there possibility of sum of ArrayList without looping
I would use bit combination to divide the stones into two groups and sum up every possible combination, comparing them to choose the one with lowest difference:
import java.util.Arrays;
import java.util.LinkedList;
public class Pile {
/**
* return solution as int, if bit is set use the "bitNumber" as index for stone
* for one side, otherwise for the other
**/
private static int divide(int[] stones) {
int solution = -1;
long minDifference = Long.MAX_VALUE;
for (int n = 0; n < (1 << (stones.length + 1)); n++) {
long sumLeft = 0;
long sumRight = 0;
for (int bit = 0; bit < stones.length; bit++) {
boolean isSet = (n & (1 << bit)) > 0;
if (isSet) {
sumLeft += stones[bit];
} else {
sumRight += stones[bit];
}
}
long diff = Math.abs(sumLeft - sumRight);
if (diff < minDifference) {
solution = n;
minDifference = diff;
}
}
return solution;
}
public static long minDiff(int[] stones) {
int solution = divide(stones);
long sumLeft = 0;
long sumRight = 0;
LinkedList<Integer> left = new LinkedList<>();
LinkedList<Integer> right = new LinkedList<>();
for (int bit = 0; bit < stones.length; bit++) {
boolean isSet = (solution & (1 << bit)) > 0;
if (isSet) {
sumLeft += stones[bit];
left.add(stones[bit]);
} else {
sumRight += stones[bit];
right.add(stones[bit]);
}
}
System.out.println("left: " + Arrays.toString(left.toArray()));
System.out.println("right: " + Arrays.toString(right.toArray()));
return Math.abs(sumRight - sumLeft);
}
}

My selection sorting code is failing on one index

I'm having great issues with my selection sort code can anyone explain to me where i'm going wrong?
this code works for the most part however when it gets to the 4/5th round it false to sort the 5 as the next lowest instead going to the 6 in the array.
this is what my output looks like. As you can see the 5 is clearly in the wrong place.
any help understand why this is would be great thank you.
[1, 9, 4, 10, 5, 3, 6, 2, 8, 7]
[1, 2, 9, 10, 5, 3, 6, 4, 8, 7]
[1, 2, 3, 10, 9, 5, 6, 4, 8, 7]
[1, 2, 3, 4, 10, 9, 5, 6, 8, 7]
[1, 2, 3, 4, 6, 10, 9, 5, 8, 7]
[1, 2, 3, 4, 6, 5, 10, 9, 8, 7]
[1, 2, 3, 4, 6, 5, 7, 10, 9, 8]
[1, 2, 3, 4, 6, 5, 7, 8, 10, 9]
[1, 2, 3, 4, 6, 5, 7, 8, 9, 10]
-
public class Selection {
void findSmallestNumberIndex(int[] numbers, int index) {
//int[] numbers = {4, 9, 2, 10, 5, 3, 6, 1, 8, 7};
int n = numbers.length;
int min_idx = index; //4
for (int j = index + 1; j < n; j++) {
if (numbers[j] < numbers[min_idx]) {
min_idx = j;
}
int temp = numbers[min_idx];
numbers[min_idx] = numbers[index];
numbers[index] = temp;
}
}
public static void main(String[] args) {
int[] numbers = {4,9,2,10,5,3,6,1,8,7};
int NumLen = numbers.length;
int[] sortedNum = new int[NumLen];
int index;
index = 0;
Selection OB = new Selection();
do {
OB.findSmallestNumberIndex(numbers, index);
index++;
System.out.println(Arrays.toString(numbers));
} while (index != (NumLen - 1));
}
}
Move the logic to adjust array outside the for loop, here's how it should look:
void findSmallestNumberIndex(int[] numbers, int index) {
//int[] numbers = {4, 9, 2, 10, 5, 3, 6, 1, 8, 7};
int n = numbers.length;
int min_idx = index; //4
for (int j = index + 1; j < n; j++) {
if (numbers[j] < numbers[min_idx]) {
min_idx = j;
}
}
int temp = numbers[min_idx];
numbers[min_idx] = numbers[index];
numbers[index] = temp;
}

Combination of subarrays

Not sure if this has been asked already but I'm having trouble printing combinations of subarrays.
Given say
int[][] x= {{1,2},{3,4,5},{6,7}};
print all valid combinations by choosing one int from each subarray.
some valid outputs are:
1,3,6
1,3,7
1,4,6
1,4,7
..
... etc
SO far my code looks like
public static void main(String args[]) {
int[][] x= {{1,2},{3,4,5},{6,7}};
for(int i = 0; i < x.length; i++){
for (int j = 0; j < 3; j++){
for (int k = 0; k < 2; k++){
System.out.println(x[0][i]+" " + x[1][j] +" "+ x[2][k]);
}
}
My code is throwing an exeption indexoutofbounds. I'm not sure where I'm going out of bounds. I know its the naive solution and brute force and theres prob a better way to solve it but this solution is the first that came across my mind.
Instead of doing i < x.length, try i < x[0].length The length of x is 3 and that of the first element is 2. Hence, the out of bounds exception. Also, it might be a good idea to get x[1].length and x[2].length instead of hard coding 3 and 2.
Try:
public class MyClass {
public static void main(String args[]) {
int[][] x= {{1,2},{3,4,5},{6,7}};
for (int i = 0; i < x[0].length; i++){
for (int j = 0; j < x[1].length; j++){
for(int k = 0; k < x[2].length; k++){
System.out.println(x[0][i] + " " + x[1][j] + " " + x[2][k]);
}
}
}
}
}
Looking for something complex written in Java 8? Here it is:
package com.test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ArrayPrint {
#SuppressWarnings("resource")
public static void main(String args[]) {
int[][] x = { { 1, 2 }, { 3, 4, 5 }, { 6, 7 } };
Stream<List<Integer>> inputs = null;
for (int[] set : x) {
List<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, Arrays.stream(set).boxed().toArray(Integer[]::new));
if (inputs == null) {
inputs = Stream.of(list);
} else {
inputs = Stream.concat(inputs, Stream.of(list));
}
}
Stream<List<List<Integer>>> listified = inputs.filter(Objects::nonNull).filter(input -> !input.isEmpty())
.map(l -> l.stream().map(o -> new ArrayList<>(Arrays.asList(o))).collect(Collectors.toList()));
List<List<Integer>> combinations = listified.reduce((input1, input2) -> {
List<List<Integer>> merged = new ArrayList<>();
input1.forEach(permutation1 -> input2.forEach(permutation2 -> {
List<Integer> combination = new ArrayList<>();
combination.addAll(permutation1);
combination.addAll(permutation2);
merged.add(combination);
}));
return merged;
}).orElse(null);
combinations.forEach(System.out::println);
}
}
Output:
[1, 3, 6]
[1, 3, 7]
[1, 4, 6]
[1, 4, 7]
[1, 5, 6]
[1, 5, 7]
[2, 3, 6]
[2, 3, 7]
[2, 4, 6]
[2, 4, 7]
[2, 5, 6]
[2, 5, 7]
With int[][] x = { { 1, 2 }, { 3, 4, 5 }, { 6, 7 }, { 8, 9, 10 } };, Output:
[1, 3, 6, 8]
[1, 3, 6, 9]
[1, 3, 6, 10]
[1, 3, 7, 8]
[1, 3, 7, 9]
[1, 3, 7, 10]
[1, 4, 6, 8]
[1, 4, 6, 9]
[1, 4, 6, 10]
[1, 4, 7, 8]
[1, 4, 7, 9]
[1, 4, 7, 10]
[1, 5, 6, 8]
[1, 5, 6, 9]
[1, 5, 6, 10]
[1, 5, 7, 8]
[1, 5, 7, 9]
[1, 5, 7, 10]
[2, 3, 6, 8]
[2, 3, 6, 9]
[2, 3, 6, 10]
[2, 3, 7, 8]
[2, 3, 7, 9]
[2, 3, 7, 10]
[2, 4, 6, 8]
[2, 4, 6, 9]
[2, 4, 6, 10]
[2, 4, 7, 8]
[2, 4, 7, 9]
[2, 4, 7, 10]
[2, 5, 6, 8]
[2, 5, 6, 9]
[2, 5, 6, 10]
[2, 5, 7, 8]
[2, 5, 7, 9]
[2, 5, 7, 10]
Thus, this code can handle any two dimensional integer array.
Regarding my suggestion from the comments try this code and look at the changes to each for loop. Instead of iterating over predetermined size like for(int k = 0; k < 2; k++) We instead iterate based on the size of the array as follows for(int k = 0; k < x[1].length; k++)
public static void main(String args[]) {
int[][] x = { { 1, 2, 3}, { 3, 4, 5 }, { 6, 7 } };
for (int j = 0; j < x[0].length; j++) {
for (int k = 0; k < x[1].length; k++) {
for (int l = 0; l < x[2].length; l++) {
System.out.println(x[0][j] + " " + x[1][k] + " " + x[2][l]);
}
}
}
}
As long as your outer array only contains three arrays you can do as shown. Otherwise you will need to be a bit more sophisticated with you loops and not hardcode the specific index like for(int k = 0; k < x[0].length; k++) Here we are directly coding index 0.
Hope this helps.
You could always declare an array of objects and cast to the data-type of your choice like this.
public class PrintArray{
public static void main(String[] args){
Object[][] myArray = {{1, 2, 3},
{4, 5, null},
{7, 8, null}};
for(int x = 0; x < myArray.length; x++){
for(int y = 0; y < 3; y++){
if(myArray[x][y] != null){
System.out.print((int)myArray[x][y]);
}
}
System.out.println();
}
}
}
I hope this helps

java ArrayList clone several times

I am trying to clone my ArrayList 4 times using a for-loop and clone() method, but I could not.
The below is the (straightforward) code I wrote:
static ArrayList<Integer> newArrList;
for (int n = 1; n <= 4; n++) {
ArrayList<Integer> arrList = new ArrayList<>();
for (int i = 1; i <= 13; i++) {
arrList.add(i);
}
newArrList = (ArrayList<Integer>) arrList.clone();
for (int i = 1; i <= 13; i++) {
newArrList.add(i);
}
}
The output is:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
It prints my arrList only 2 times, but I want it 4 times. Like that:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
Is it the best way to clone an ArrayList multiple times? and what am I doing wrong?
Your code seems a little too confusing to me, so I'm unable to point out where exactly you went wrong.
The first thing I don't understand is why you create your test list 4 times (inside the main loop). Shouldn't it be created just once?
Then doing a clone and adding the 13 elements afterwards put the content twice in the new list. Once as a copy of the original content, and then as hard-coded data. I don't understand the motivation behind that.
Anyway, I would just create a new (empty) list and add all the elements of the original list 4 times using addAll:
// create test list
ArrayList<Integer> arrList = new ArrayList<>();
for (int i = 1; i <= 13; i++) {
arrList.add(i);
}
// clone
ArrayList<Integer> newArrList = new ArrayList<>();
for (int i = 0; i < 4; i++) {
newArrList.addAll(arrList);
}

Pascals triangle in one loop

Is it possible to write the pascal's triangle by using one loop ? I have written it by using more than one loop and it is working fine.
Heck, I'll make my comment an answer:
As a hint, I would create a method that takes as input the number of rows of the triangle you want to produce, then at the beginning of the method calculate total number of items this will translate out to, and then have your for loop loop through all the items. Inside the loop, you can easily calculate which row you're on and which column you're on, and then use this information to create your item value.
the code you want is Here
or
package net.yogesh.test;
import java.util.ArrayList;
import java.util.List;
public class pascal3 {
public static void main(String[] args) {
int noOfRows = 10;
int counter = 1;
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list = itMe(list, counter,noOfRows);
}
public static List<Integer> itMe(List<Integer> list, int counter,int noOfRows) {
System.out.println(list);
List<Integer> tempList = new ArrayList<Integer>();
tempList.add(1);
for (int i = 1; i < list.size(); i++) {
tempList.add(list.get(i) + list.get(i-1));
}
tempList.add(1);
if(counter != noOfRows)
itMe(tempList, ++counter,noOfRows);
return tempList;
}
}
Note
here output is as expected
but if you want in formatted view than you need to use extra loop.
Output
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]

Categories