Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 11 months ago.
Improve this question
Hi Im searching a fast dynamic programming / formula solution. For following algorithm, example:
init := 1
elements := 4
steps := 3
step 1. [1,1,1,1] init is placed in each index
step 2. [1,2,3] index i is calculated by sum of former step index 0 until inclusive step 1 index i, arraysize get's decremented by one.
step 3. [1,3] Same procedere like step 2 but using step 2 as base.
final step solution := 4 final step is summing up last stepelements.
Is there a faster way than summing up manually?
Sample Code:
long calc(int init,int elements,int steps){
int[] dp1 = new int[elements-1];
Arrays.fill(dp1, init);
int[] dp2 = new int[elements-1];
for(int i = 0; i < steps-1; i++){
for(int j = 0,cur = 0; j < elements-i-1; j++){
dp2[j] = cur = cur + dp1[j];
}
System.arraycopy(dp2,0,dp1,0,elements-i-1);
Arrays.fill(dp2, 0);
}
return Arrays.stream(Arrays.copyOf(dp1,elements-steps+1)).sum();
}
You're doing a lot of copying and filling where none is necessary. Try it like this.
static long myCalc(int init, int elements, int steps) {
if (steps > elements+1) {
System.out.println("Steps too large for # of elements");
return -1;
}
int[] dp1 = new int[elements - 1];
Arrays.fill(dp1, init);
int len = dp1.length;
for (int j = 0; j < steps - 1; j++) {
for (int i = 1; i < len; i++) {
dp1[i] = dp1[i - 1] + dp1[i];
}
len--;
}
return Arrays.stream(dp1).limit(len+1).sum();
}
Added improvement. For each step, one less value is added. So adjust the for loop iterations to accommodate.
You might want to look at the Arrays.parallelPrefix method. From the java doc:
Cumulates, in parallel, each element of the given array in place, using the supplied function. For example if the array initially holds [2, 1, 0, 3] and the operation performs addition, then upon return the array holds [2, 3, 3, 6]. Parallel prefix computation is usually more efficient than sequential loops for large arrays.
So something like below might be what you are looking for :
long calc(int init,int elements,int steps){
int[] arr = new int[elements];
Arrays.fill(arr,init);
int[] curr = arr;
for (int i = 1; i < steps; i++){
Arrays.parallelPrefix(curr, Integer::sum);
curr = Arrays.copyOf(curr,curr.length-1);
System.out.println(Arrays.toString(curr)); // just to check the sub steps, remove if I get the discription of the steps right
}
return Arrays.stream(curr).sum();
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am trying to shift all elements in my array to the left by 1, I am trying to remove the element 3 at index 0 from my array but the output I receive is completely different than what I expect. I don't understand why I receive this output.
The output I expect to receive is [2,2,3,0] I expect a zero on the last index because I shifted all elements to the left so there would be no value shifted to the last index. But I instead received [2,2,3,3]. I don't understand why a 3 is in the last index?
int [] nums = {3,2,2,3};
int length = nums.length;
for (int j = 1; j < length; j++) {
nums [j - 1] = nums [j];
}
return nums.length;
Try this, I just set the last one to 0:
int[] nums = {3,2,2,3};
int length = nums.length;
for (int j = 1; j < length; j++) {
nums [j - 1] = nums [j];
}
nums[nums.length - 1] = 0;
for (int number : nums) {
System.out.print(number);
}
I set the last number to 0 because you only changed the indices 0, 1 and 2 with your for-loop so that the last index, i.e. index 3, keeps the value 3.
So you get this: 2230.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
Ive been trying to understand the merge portion of mergesort for a few hours now, and Ive looked at a bunch of tutorials and walkthroughs. And im not understanding the merge part of mergesort. Theoretically, I understand it. But trying to implement it through code is where Im having a hard time. It's not like I dont understand any of the merge portion of it. I get why you need a couple pointers to keep track of the indices and the reasoning behind the conditional statement in the while loop. But after that I get stuck. I wrote a comment in the merge method on where im stuck. If anyone could just explain to me what I need to code in Java and the reasoning behind it, it'd be great.
EDIT: Added two new while loops the the merge method. All thats left I think for me to do is how to copy the sorted partitions into the input array. I think after that it should be working fine... hopefully.
EDIT2: Nevermind the above, I just saw that its not sorting it correctly. Hopefully someone can just modify my code and explain there process
public static void merge(int[] input, int start, int mid, int end) {
if (input[mid - 1] <= input[mid]) {
return;
}
int i = start;
int j = mid;
int tempIndex = 0;
int[] temp = new int[end - start];
//If i is greater than mid or j is greater than end, that means that half of the array is sorted
while (i < mid && j < end) {
temp[tempIndex++] = input[i] <= input[j] ? input[i++] : input[j++];
}
//added the two loops below
while(i < mid){
temp[tempIndex++] = input[i++];
}
while(j < end){
temp[tempIndex++] = input[j++];
}
}
```
MergeSort is a divide and conquor strategy.
Let's say you have 8 elements.
The 8 elements get split into 4 elements each (left/right) and mergeSort is invoked on each of them. We'll ignore merge for now and delve deeper.
The 4 elements are further split into 2 elements each, and mergeSort is invoked on the 2 element array.
The 2 elements are further split into 1 elements each, and mergeSort is invoked on each of these at which time, it returns without doing anything.
So we are finally at the first invocation of merge. So what does merge do? Merge joins 2 SORTED lists. When they are 1 element each, it's just a matter of picking one over the other. So lets skip forward to the 4 elements and provide an example below:
By the time the 4 element sub-list invokes merge, it may have the following:
1 3 2 4
Each sub-array (1, 3) and (2, 4) are already sorted by the previous merge. So we now need to sort the array while merging them like this (I will use a separate output array to demonstrate what should be happening but it can be done in place):
for (int i = 0, j = 2, k = 0; k < 4; k++)
{
int idx;
if ((j >= 4) || (i < 2 && inputArray[i] < inputArray[j]))
{
idx = i++;
}
else // j < 4 && (i > 2 || inputArray[j] < inputArray[i])
{
idx = j++;
}
outputArray[k] = inputArray[idx];
}
As you can see, initially we have i pointing to 1, j pointing to 2. Because 1 < 2, i is selected, and the 1 is output. Because i was selected, i gets incremented. Now, we have i pointing to 3 and j pointing to 2. Because 2 < 3, j gets selected... and so on until we run out of elements.
And after the merge, it will get called on the larger array with 2 4-element sides, repeating the above.
Below is the generalized code without hard coding
public void Merge(int[] input, int start, int mid, int end)
{
if (input[mid - 1] <= input[mid])
{
}
else
{
int[] tmp = new int[end - start];
for (int i = start, j = mid, k = 0; k < tmp.Length; k++)
{
int idx;
if ((j >= end) || (i < mid && input[i] < input[j]))
{
idx = i++;
}
else // j < end && (i > mid || inputArray[j] < inputArray[i])
{
idx = j++;
}
tmp[k] = input[idx];
}
for (int i = start, j = 0; i < end; i++, j++)
{
input[i] = tmp[j];
}
}
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I was trying to solve a problem in a coding trainer. But, I just could not figure this problem for the life of me.
Here is the problem:
You are given an m x n 2D image matrix where each integer represents a pixel. Flip it in-place along its horizontal axis.
Example:
Input image :
1 1
0 0
Modified to :
0 0
1 1
I tried swapping rows as I traversed 2d array down the row for test case:
1,2,3
4,5,6
7,8,9
But, I end up getting
4,5,6
7,8,9
1,2,3
instead of
{{7,8,9},
{4,5,6},
{1,2,3}}
Here is the answer code.
public static void flipHorizontalAxis(int[][] matrix) {
int r = matrix.length - 1, c = matrix[0].length - 1;
int temp = 0;
for(int i = 0; i <= r/2; i++){
for(int j = 0; j <= c; j++){
temp = matrix[i][j];
matrix[i][j] = matrix[r-i][j];
matrix[r-i][j] = temp;
}
}
}
I still do not understand the answer code. Specifically, why the outer loop has "i <= r/2" and the swap has "matrix[r-i]" in the index. Why r/2 and r-i? I really do not understand why and I am totally stuck.
Can someone explain those lines so I can understand the code?
Here is the expected output for test cases:
1
{{1}}
1,0,0
0,0,1
{{0,0,1},{1,0,0}}
1,0
{{1,0}}
1,2,3
4,5,6
7,8,9
{{7,8,9},{4,5,6},{1,2,3}}
1,0,1
1,0,1
{{1,0,1},{1,0,1}}
Focusing on only the double loop:
for (int i=0; i <= r/2; i++){
for (int j=0; j <= c; j++){
temp = matrix[i][j];
matrix[i][j] = matrix[r-i][j];
matrix[r-i][j] = temp;
}
}
The outer loop in i only ranges up to (and including) one half the height of the matrix because we want to swap each array with its "mirror" image on the other side of the median row. That is, for a 3x3 matrix we want to do the following:
1,2,3 i=0
4,5,6
7,8,9 r-i=matrix.length-1 = 3-1 = 2
(swap these rows, i=i+1)
7,8,9
4,5,6 i=1, r-i=1
1,2,3
(swap the median row with itself, nothing changes)
If we were to allow the outer loop to run the full height of the input matrix, then after the median row we would actually undo the swap already done, and would just end up the original input matrix.
The number of row swaps you need to do is matrix.length/2 - 1. You could have written:
for (int i = 0; i < matrix.length/2; i++)
instead of:
for(int i = 0; i <= r/2; i++)
for matrices with an odd number of rows, matrix.length/2 and r/2 are equal, which means that in the second form, because of the <=, you will swap the middle row with itself, which is useless, so I prefer the first form.
Now the index r-i will go downwards from the index of the last row (r = matrix.length-1). It's the index of the row that must be swapped with the one at index i.
Note that the the rows themselves are array, and it would be more efficient to swap the whole rows instead of each individual element, so here is a better solution:
public static void flipHorizontalAxis(int[][] matrix) {
int r = matrix.length-1;
for (int i = 0; i < matrix.length/2; i++) {
int[] temp = matrix[i];
matrix[i] = matrix[r - i];
matrix[r - i] = temp;
}
}
Or:
public static void flipHorizontalAxis(int[][] matrix) {
int r = matrix.length;
for (int i = 0; i < matrix.length/2; i++) {
--r;
int[] temp = matrix[i];
matrix[i] = matrix[r];
matrix[r] = temp;
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I know that similar questions have been asked and I have researched
many websites. I have tried to use some of the answers but my code is
still not working.
I am going through a previous assignment to help build my knowledge
of Java. Please forgive any errors in my code, I am still learning
Java.
Here is my question:
Implement a method count which, given an array of integer elements, returns another array containing the number of occurrences of each integer {0, ..., r} in the input array, where r is an integer to show the upper boundary of the integers that you need to count.
The returned array of counts will be of size r + 1, where the element at each index i corresponds to the number of occurrences of integer i (with i in {0, ..., r}).
Elements in the input array outside of the integer range from 0 to r can be ignored.
For example, given the input [0, 8, 1, 3, 1, 3, 10, 3] with r is 4, the output should be [1, 2, 0, 3, 0].
If the input array is null or of length 0, this will return null.
Space requirements: Method count should only use additional space for the count array.
Time requirements: The counts should be calculated in a single pass through the input array.
Here is what I've done so far, it doesn't meet the requirements so I need help in order to find the right solution:
public static int[] count(int[] arr, int r) {
int[] count = new int[r + 1];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < r; j++) {
if (arr[i] == j) {
count[i]++;
}
}
}
return count;
}
You are really close, but seems maybe a small bit is wrong.
int[] count = new int[r + 1];
for (int i = 0; i < arr.length; i++) {
if( arr[i] <= r) {
count[arr[i]]++;
}
}
I think the above will work, if you think about it, each element of arr corresponds to an index in count as long as that index is within {0...r}, so we check that the value is within that range, then we increment the integer at that index within count.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I would like to for-loop a set of numbers and change their positions in each line. It reads a series of integers (at most 10) until a non-integer has been inputted from the keyboard. My expected result is something like this:
>> 4 0 3 4 2 q
4 0 3 4 2
0 3 4 2 4
3 4 2 4 0
4 2 4 0 3
2 4 0 3 4
Can anybody teach me how to deal with it? Thanks in advance.
With some knowledge of modular arithmetic you can fold an array around into a circle. Observe that the starting point of each index shifts to the right by one place from the starting point of the previous row. So you do your loop like this:
n := length of the array
for i = 0 to n-1 (assuming the array is zero-based)
j := i
do loop
print(array[j])
j := j + 1
j := j%n
until j = i
end for
This is a language independent pseudo-code. Adapt it to whatever language your're coding in.
Here is a method to shift the numbers like you want. I took the liberty of commenting it to give you a better understanding of what's going on.
public static void shift(int[] numbers) {
//Store the first element
int first = numbers[0];
//Start for-loop at the beginning of the array, stop before the last element
for (int i = 0; i < numbers.length - 1; i++)
//Take the number at the next index (i + 1) and store it in the current index (i)
numbers[i] = numbers[i + 1];
//Don't forget about the first number!
numbers[numbers.length - 1] = first;
}
The following snippet should change the contents of the array to be {0, 3, 4, 2, 4}
shift(new int[] {4, 0, 3, 4, 2})
Here is a complete, runnable class file.
import java.util.Arrays;
public class Shift {
public static void main(String[] args) {
int[] numbers = new int[] {4, 0, 3, 4, 2};
shift(numbers);
System.out.println(Arrays.toString(numbers));
}
public static void shift(int[] numbers) {
//Store the first element
int first = numbers[0];
//Start for-loop at the beginning of the array, stop before the last element
for (int i = 0; i < numbers.length - 1; i++)
//Take the number at the next index (i + 1) and store it in the current index (i)
numbers[i] = numbers[i + 1];
//Don't forget about the first number!
numbers[numbers.length - 1] = first;
}
}
EDIT:
To use an ArrayList called list, you can use the following snippet:
list.add(list.remove(0));
This is because ArrayList.remove(int) will return the object removed from the array, so we can just add it on to the end.