数组子集不等和

时间:2019-05-28 16:58:44

标签: java

我需要编写一个将数组分为2部分{4,5,2,1,3}的函数,以便第一个数组中的和大于第二个数组中的和,而第一个数组的长度小于秒的总和。它们的总和是总和,并且没有任何交点。所以答案是{4,5}。

import java.util.ArrayList;
import java.util.Stack;

public class DP2 {

    public static void main(String args[]) {
        int[] arr= {5,2,10,4,1,11};
        ArrayList<Integer> list=new ArrayList<>();
        //calculate sum
        int finalSum=0;
        /*
        for(int i: arr)
            finalSum+=arr[i];
            */
        int len=arr.length;
        int mid=(len)/2;
        System.out.println(mid);
        int sum=0;
        //initialize 2 pointers

        //will use a stack
        Stack<Integer> stack = new Stack<Integer>();

        int i=0,j=len-1;
        int max=Integer.MIN_VALUE;
        while(i < j ) {
            //int max=Math.max(arr[i], arr[j]);
        //  System.out.println(max);
            while(stack.size() < mid) {


                max=Math.max(arr[i], arr[j]);
                stack.push(max);
                //System.out.println(stack.size());
            //  System.out.println(stack.peek());
                i++;
                j--;
            }

        //  max=Math.max(arr[i], arr[j]);
            i++;
            j--;

            if(stack.size() < mid  && stack.peek() < max  ) {




                    stack.pop();
                    stack.push(max);


                }




        }


        while(!stack.isEmpty())
            System.out.println(stack.pop());




        }
    }

它不会返回预期的答案。它没有像我编写的代码那样从堆栈中弹出。有人可以帮我做错什么吗?

2 个答案:

答案 0 :(得分:1)

据我所知,没有任何问题,一切都按预期进行。唯一的问题是弹出操作给您相反的结果。我已经在以下代码中修复了该问题:

Integer[] result = new Integer[stack.size()];
for (int i1 = result.length - 1; i1 >= 0 && !stack.isEmpty(); i1--) {
    result[i1] = stack.pop();
}
System.out.println(Arrays.toString(result));

输出 [4, 5]

编辑:此处要求完全解决您的问题:

/**
 * Convert an array of primitive numbers to Integer objects.
 */
private static Integer[] intToInteger(int[] array) {
    return Arrays.stream(array).boxed().toArray( Integer[]::new );
}

/**
 * Converts a primitive integer array to an ArrayList.
 */
private static ArrayList<Integer> intArrayTolist(int[] array) {
    return new ArrayList<>(Arrays.asList(intToInteger(array)));
}

public static void main(String[] args) {

    int[] arr0 = { 5, 2, 10, 4, 1, 11 };

    /* determine the size of the first array */
    float quotient = (float)arr0.length / 2;
    int mid = (int) Math.floor(quotient);

    int size = quotient != mid ? mid : mid - 1;

    /* Initialize arrays here */
    Integer[] arr1 = new Integer[size];
    Integer[] arr2 = new Integer[arr0.length - mid];

    List<Integer> list = intArrayTolist(arr0);

    /* Populate the first array with largest values
     * found within the main array
     */
    for (int i = 0; i < size; i++) {
        /*
         * Find out the largest value in the main array
         * and add that value to the first array
         */
        arr1[i] = java.util.Collections.max(list);
        list.remove(arr1[i]);
    }

    arr2 = list.toArray(arr2);
    int sum = Arrays.stream(arr0).sum();

    System.out.println("First array: " + Arrays.toString(arr1));
    System.out.println("Second array: " + Arrays.toString(arr2));
    System.out.println("Sum of all numbers: " + sum);
}

输出

First array: [11, 10]
Second array: [5, 2, 4, 1]
Sum of all numbers: 33

请注意,它可能不如我希望的那么优雅,但可以完成工作。我将查看是否可以做一些进一步的清理和优化,因为我感觉其中存在很多冗余。这只是一个快速的模拟,因此您可以拥有一些实际可行的功能。

答案 1 :(得分:0)

我使用了递归。这是我的方法:

@Test
public void stackoverflow() {
    int[] array = { 39, 2, 3, 40, 0, 0, 0 };
    System.out.println("index is " + method(array, 0));
}

String method(int[] array, int i) {
    if (i < array.length / 2 && sum(array, 0, i) > sum(array, i + 1, array.length - 1)) {
        return "the sub array goes from 0 to " + i;
    }
    else if (i >= array.length / 2 && sum(array, array.length - 1 - i + array.length / 2, array.length - 1) > sum(array, 0, array.length - i - 2 + array.length / 2)) {
        int index = array.length - 1 - i + array.length / 2;
        return "the sub array goes from " + index + " to " + (array.length - 1);
    }
    return method(array, i + 1);
}

int sum(int[] array, int i, int j) {
    int sum = 0;
    for (int k = i; k <= j; k++) {
        sum = sum + array[k];
    }
    return sum;
}

这是解释:您从数组的位置0开始。如果[0]处元素的总和大于从位置[1]到[n-1]的总和,就可以完成。如果不是,则调用相同的逻辑,将[0]和[1]的和与[2]和[n-1]的和进行比较。由于您正在寻找最小的数组,因此当您击中数组的一半(n / 2)时,将从数组的末尾开始执行相同的操作。

我的逻辑返回数组的索引。索引表示包含较大和的子数组的最后一个元素或第一个元素。例如,在这种情况下:

{ 0, 0, 0, 0, 40, 1, 2, 3 }

它将返回“ 4”。 [4]是此元素:

{ 0, 0, 0, 0, 40, 1, 2, 3 }
               *

在这里清楚的是,如果索引> n / 2,则子数组将从索引变为n-1。如果不是,则子数组从0变为n / 2。