How to optimally divide an array into two subarrays so that sum of elements in both are same, otherwise give an error?

前端 未结 22 859
一生所求
一生所求 2020-12-02 11:20

How to optimally divide an array into two subarrays so that sum of elements in both subarrays is same, otherwise give an error?

Example 1

Given the array

相关标签:
22条回答
  • 2020-12-02 11:55
    package PACKAGE1;
    
    import java.io.*;
    import java.util.Arrays;
    
    public class programToSplitAnArray {
    
        public static void main(String args[]) throws NumberFormatException,
                IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("enter the no. of elements to enter");
            int n = Integer.parseInt(br.readLine());
            int x[] = new int[n];
            int half;
            for (int i = 0; i < n; i++) {
    
                x[i] = Integer.parseInt(br.readLine());
            }
            int sum = 0;
            for (int i = 0; i < n; i++) {
                sum = sum + x[i];
            }
            if (sum % 2 != 0) {
                System.out.println("the sum is odd and cannot be divided");
                System.out.println("The sum is " + sum);
            }
    
            else {
                boolean div = false;
                half = sum / 2;
                int sum1 = 0;
                for (int i = 0; i < n; i++) {
    
                    sum1 = sum1 + x[i];
                    if (sum1 == half) {
                        System.out.println("array can be divided");
                        div = true;
                        break;
                    }
    
                }
                if (div == true) {
                    int t = 0;
                    int[] array1 = new int[n];
                    int count = 0;
                    for (int i = 0; i < n; i++) {
                        t = t + x[i];
                        if (t <= half) {
                            array1[i] = x[i];
                            count++;
                        }
                    }
                    array1 = Arrays.copyOf(array1, count);
                    int array2[] = new int[n - count];
                    int k = 0;
                    for (int i = count; i < n; i++) {
                        array2[k] = x[i];
                        k++;
                    }
                    System.out.println("The first array is ");
                    for (int m : array1) {
    
                        System.out.println(m);
                    }
                    System.out.println("The second array is ");
                    for (int m : array2) {
    
                        System.out.println(m);
                    }
                } else {
                    System.out.println("array cannot be divided");
                }
            }
        }
    
    }
    
    0 讨论(0)
  • 2020-12-02 11:57

    Found solution here

    package sort;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class ArraySumSplit {
    
    public static void main (String[] args) throws Exception {
    
        int arr[] = {1 , 2 , 3 , 4 , 5 , 5, 1, 1, 3, 2, 1};
        split(arr);
    
    }
    
    static void split(int[] array) throws Exception {
        int sum = 0;
        for(int n : array) sum += n;
        if(sum % 2 == 1) throw new Exception(); //impossible to split evenly
        List<Integer> firstPart = new ArrayList<Integer>();
        List<Integer> secondPart = new ArrayList<Integer>();
        if(!dfs(0, sum / 2, array, firstPart, secondPart)) throw new Exception(); // impossible to split evenly;
        //firstPart and secondPart have the grouped elements, print or return them if necessary.
        System.out.print(firstPart.toString());
        int sum1 = 0;
        for (Integer val : firstPart) {
            sum1 += val;
        }
        System.out.println(" = " + sum1);
    
        System.out.print(secondPart.toString());
        int sum2 = 0;
        for (Integer val : secondPart) {
            sum2 += val;
        }
        System.out.println(" = " + sum2);
    }
    
    static boolean dfs(int i, int limit, int[] array, List<Integer> firstPart, List<Integer> secondPart) {
        if( limit == 0) {
            for(int j = i; j < array.length; j++) {
                secondPart.add(array[j]);
            }
            return true;
        }
        if(limit < 0 || i == array.length) {
            return false;
        }
        firstPart.add(array[i]);
        if(dfs(i + 1, limit - array[i], array, firstPart, secondPart)) return true;
        firstPart.remove(firstPart.size() - 1);
    
        secondPart.add(array[i]);
        if(dfs(i + 1, limit, array, firstPart, secondPart)) return true;
        secondPart.remove(secondPart.size() - 1);
        return false;
    }
    }
    
    0 讨论(0)
  • 2020-12-02 11:57

    Algorithm:

    Step 1) Split the array into two
    Step 2) If the sum is equal, split is complete
    Step 3) Swap one element from array1 with array2, guided by the four rules:
       IF the sum of elements in array1 is less than sum of elements in array2
          Rule1:
             Find a number in array1 that is smaller than a number in array2 in such a way that swapping of          these elements, do not increase the sum of array1 beyond the expected sum. If found, swap the          elements and return.
          Rule2:
             If Rule1 is not is not satisfied, Find a number in array1 that is bigger than a number in array2 in          such a way that the difference between any two numbers in array1 and array2 is not smaller than          the difference between these two numbers.
       ELSE
          Rule3:
             Find a number in array1 that is bigger than a number in array2 in such a way that swapping these          elements, do not decrease the sum of array1 beyond the expected sum. If found, swap the
             elements and return.
          Rule4:
             If Rule3 is not is not satisfied, Find a number in array1 that is smaller than a number in array2 in          such a way that the difference between any two numbers in array1 and array2 is not smaller than          the difference between these two numbers.
    Step 5) Go to Step2 until the swap results in an array with the same set of elements encountered already Setp 6) If a repetition occurs, this array cannot be split into two halves with equal sum. The current set of           arrays OR the set that was formed just before this repetition should be the best split of the array.

    Note: The approach taken is to swap element from one array to another in such a way that the resultant sum is as close to the expected sum.

    The java program is available at Java Code

    0 讨论(0)
  • 2020-12-02 11:58

    First, if the elements are integers, check that the total is evenly divisible by two- if it isn't success isn't possible.

    I would set up the problem as a binary tree, with level 0 deciding which set element 0 goes into, level 1 deciding which set element 1 goes into, etc. At any time if the sum of one set is half the total, you're done- success. At any time if the sum of one set is more than half the total, that sub-tree is a failure and you have to back up. At that point it is a tree traversal problem.

    0 讨论(0)
  • 2020-12-02 11:58

    https://github.com/ShubhamAgrahari/DRjj/blob/master/Subarray_Sum.java

    package solution;

    import java.util.Scanner;

    public class Solution {

    static int SplitPoint(int arr[], int n) { int leftSum = 0; for (int i = 0 ; i < n ; i++) leftSum += arr[i]; int rightSum = 0; for (int i = n-1; i >= 0; i--) { rightSum += arr[i]; leftSum -= arr[i] ; if (rightSum == leftSum) return i ; } return -1; } static void output(int arr[], int n) { int s = SplitPoint(arr, n); if (s == -1 || s == n ) { System.out.println("Not Possible" ); return; } for (int i = 0; i < n; i++) { if(s == i) System.out.println(); System.out.print(arr[i] + " "); } } public static void main (String[] args) { Scanner sc= new Scanner(System.in); System.out.println("Enter Array Size"); int n = sc.nextInt(); int arr[]= new int[n]; for(int i=0;i<n;i++) { arr[i]=sc.nextInt(); } output(arr, n); } }
    0 讨论(0)
  • 2020-12-02 11:59

    very simple solution with recursion

    public boolean splitArray(int[] nums){
                return arrCheck(0, nums, 0);
            }
    
    public boolean arrCheck(int start, int[] nums, int tot){
                if(start >= nums.length) return tot == 0;
                if(arrCheck(start+1, nums, tot+nums[start])) return true;
                if(arrCheck(start+1, nums, tot-nums[start])) return true;
                return false;
            }
    
    0 讨论(0)
提交回复
热议问题