我需要编写一个将数组分为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());
}
}
它不会返回预期的答案。它没有像我编写的代码那样从堆栈中弹出。有人可以帮我做错什么吗?
答案 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。