I'm trying to understand question and solving it using java.
But first I'm not able to understand properly.
Here is the question:
You are given an array a of length n and an integer c.
The value of some array b of length k is the sum of its elements except for the smallest. For example, the value of the array [3, 1, 6, 5, 2] with c = 2 is 3 + 6 + 5 = 14.
Among all possible partitions of a into contiguous subarrays output the smallest possible sum of the values of these subarrays.
Input
The first line contains integers n and c (1 ≤ n, c ≤ 100 000).
The second line contains n integers ai (1 ≤ ai ≤ 109) — elements of a.
Output
Output a single integer — the smallest possible sum of values of these subarrays of some partition of a.
Examples
inputCopy
3 5
1 2 3
output
6
inputCopy
12 10
1 1 10 10 10 10 10 10 9 10 10 10
output
92
inputCopy
7 2
2 3 6 4 5 7 1
output
17
inputCopy
8 4
1 3 4 5 5 3 4 1
output
23
In the third example one of the optimal partitions is [2, 3], [6, 4, 5, 7], [1] with the values 3, 13 and 1 respectively.
My Understanding:
1) Partition is being being done within continuous numbers. Correct ?
2) What is the significance of Integer c in input ?
3) How is being done in third example ? I mean after having subarrays, How 13 came out from second subarray ?
Can anyone help me to understand the question ? I can write code myself.
Related
I need an array of 15 elements with random numbers (1-15). I should enter a value at a specific location, but the values after my selected location should go on by one location. ex: I have
1 12 3 8 9 3 5 4 4 10 3 7 7 2 1 and I want to insert the number "5" at location 3 and now I should have 1 12 5 3 8 9 3 5 4 4 10 3 7 7 2 .
You have an idea?
Thanks in advance.
Use a ArrayList as suggested in the comments. When you have to use a array you can take something like
for (int i = array.length - 2; i >= position; i--)
array[i+1] = array[i];
array[position] = value;
with position the index of the array you want to change and value the value to insert.
I've been having some trouble with a homework assignment for my Java class. In it, we're supposed to take in an integer between 1 and 13 and display three different triangles consisting of numbers. For example, if I were to enter 5, the result would be:
Triangle 1
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
Triangle 2
1
2 6
3 7 10
4 8 11 13
5 9 12 14 15
Triangle 3
5
4 9
3 8 12
2 7 11 14
1 6 10 13 15
I've already got the first Triangle going fine, but my big concern is the second triangle. I haven't attempted the third one yet. The other thing is that my Professor is picky about what method we use in creating the project. In other words, we can only use what he has taught us. He told us to use the System.out.printf("%3d", n) statement to space out the characters and we have to create them within a separate class.
The code for the first triangle is as follows:
void triangle1(int n)
{
int k = 1;
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < 1; j++)
{
System.out.printf("%3d", n);
k += 1;
}
System.out.println();
}
}
So, pretty much, I need to follow that standard to create the other two triangles, but I'm really stuck on the second one and I don't know where to start. Any help will be much appreciated!
Here is the way I would approach it.
Programs print one line at a time, you cannot print half a line then start to print another line.
With that being said, you should recognize the pattern in the triangles.
1
2 6
3 7 10
4 8 11 13
5 9 12 14 15
You have the first number n, then you see the next row starts with n + 1. The next number starts in the row is (n + 1) + t where t = 4. There is a pattern there.
The third row follows the same pattern.
The first number is (n + 1) then you can calculate the others by + (t - 1)
This can be done with a for loop, like you did in the first time.
For the last triangle you can use the same process, just change the signs and t would equal something different.
Algorithm writing is all about identifying patterns.
If you look closely, you'll see there's a repeating pattern between each number and the one that follows on a given line.
3 7 10 => [3 & 7 differ by 4][7 & 10 differ by 3]
4 8 11 13 => [4 & 8 differ by 4][8 & 11 differ by 3][11 & 13 differ by 2]
5 9 12 14 15 => [... differ by 4][... by 3][... by 2][... by 1]
You can use that information to make the second triangle. I'll leave the rest to you. I hope that helps!
Seems you are a CS-Student, thus I will not present a finished solution. I'll give you some hints how I would solve this.
This is what the print statement has to do:
for i=1 j=0 print 1
for i=2 j=0 print 2
for i=2 j=1 print 6
for i=3 j=0 print 3
for i=3 j=1 print 7
for i=3 j=2 print 10
Find a formula that calculates the correct output from i and j, its a simple linear combination.
use I can't divide into segads. As for my above example if 5 threads are set, then first segment would take 2 first object, and second 3th and 4th, so they dont find dups, but there are dups if we merge them, its 2th and 3th.
There could be more complex strate take from first threads .. ah nevermind, to hard to explain.
And ofcourse, problelection itself in my plans.
Tha
EDIT:
InChunk, and then continue analyzing that chunk till the end. ;/
I think the process of dividing up the items to be de-duped is going to have to look at the end of the section and move forward to encompass dups past it. For example, if you had:
1 1 2 . 2 4 4 . 5 5 6
And you dividing up into blocks of 3, then the dividing process would take 1 1 2 but see that there was another 2 so it would generate 1 1 2 2 as the first block. It would move forward 3 again and generate 4 4 5 but see that there were dups forward and generate 4 4 5 5. The 3rd thread would just have 6. It would become:
1 1 2 2 . 4 4 5 5 . 6
The size of the blocks are going to be inconsistent but as the number of items in the entire list gets large, these small changes are going to be insignificant. The last thread may have very little to do or be short changed altogether but again, as the number of elements gets large, this should not impact the performance of the algorithm.
I think this method would be better than somehow having one thread handle the overlapping blocks. With that method, if you had a lot of dups, you could see it having to handle a lot more than 2 contiguous blocks if you were unlucky in the positing of the dups. For example:
1 1 2 . 2 4 5 . 5 5 6
One thread would have to handle that entire list because of the 2s and the 5s.
I would use a chunk-based division, a task queue (e.g. ExecutorService) and private hash tables to collect duplicates.
Each thread in the pool will take chunks on demand from the queue and add 1 to the value corresponding to the key of the item in the private hash table. At the end they will merge with the global hash table.
At the end just parse the hash table and see which keys have a value greater than 1.
For example with a chunk size of 3 and the items:
1 2 2 2 3 4 5 5 6 6
Assume to have 2 threads in the pool. Thread 1 will take 1 2 2 and thread 2 will take 2 3 4. The private hash tables will look like:
1 1
2 2
3 0
4 0
5 0
6 0
and
1 0
2 1
3 1
4 1
5 0
6 0
Next, thread 1 will process 5 5 6 and thread 2 will process 6:
1 1
2 2
3 0
4 0
5 2
6 1
and
1 0
2 1
3 1
4 1
5 0
6 1
At the end, the duplicates are 2, 5 and 6:
1 1
2 3
3 1
4 1
5 2
6 2
This may take up some amount of space due to the private tables of each thread, but will allow the threads to operate in parallel until the merge phase at the end.
I am working on a school homework problem. I need to create 2 int[] arrays. The first array int[10] is filled with random integers. The second array has the same numbers as in the first array, but without any duplicates.
For example, assume my first array is 1,2,2,3,1,5,5,7,9,9. My second array would then be 1,2,3,5,7,9.
Could someone please point me in the right direction to solving this problem.
Put the numbers into a Set. Then retrieve numbers from the Set. Simple! Duplicates will automatically be removed!
I would do the following (assuming that it is homework and you shouldn't be doing anything too complicated)...
Sort the array using java.util.Arrays.sort(myArray); - this will order the numbers, and make sure that all repeating numbers are next to each other.
Loop through the array and keep a count of the number of unique numbers (ie compare the current number to the next number - if they're different, increment the counter by 1)
Create your second int[] array to the correct size (from point 2)
Repeat the same process as point 2, but fill your new array with the unique numbers, rather than incrementing a counter.
This should be enough to get you moving in the right direction. When you have some code, if you still have questions, come back to us and ask.
I recommend using a Set , but here's a way to do it without using a Set. (Note: This will work, but don't ask me about the efficiency of this!)
Have a function like this -
public static boolean isNumberInArray(int[] array, int number)
{
for(int i=0; i<array.length; i++)
{
if(number == array[i])
return true;
}
return false;
}
Now use this function before you make an insert into the new array. I leave you to figure out that part. It's homework after all!
Hints(WATTO explains it better):
a = sorted first array
lastItem = a[0]
append lastItem into new array
for i in 1 to length(a):
if a[i] != lastItem:
append a[i] into new array
lastItem = a[i]
#WATTO Studios has a good approach. Sorting is always useful when duplicates are involved.
I will suggest an alternative method using hash tables:
Create a hashing structure with an integer as key (the number in the original array) and a counter as a value.
Go through the original array and for each number encountered increment it's corresponding counter value in the hash table.
Go through the original array again. For each number check back the hash table. If the counter associated is greater than 1, remove the value and decrement the counter.
Let's see a practical case:
4 5 6 4 1 1 3
First pass will create the following table:
1 -> 2
3 -> 1
4 -> 2
5 -> 1
6 -> 1
Second pass step by step:
4 5 6 4 1 1 3
^
4 has a counter of 2 -> remove and decrement:
1 -> 2
3 -> 1
4 -> 1
5 -> 1
6 -> 1
5 6 4 1 1 3
^
5 has a counter of 1 -> ignore
6 has a counter of 1 -> ignore
4 has a counter of 1 -> ignore
1 has a counter of 2 -> remove and decrement
1 -> 1
3 -> 1
4 -> 1
5 -> 1
6 -> 1
5 6 4 1 3
^
1 has a counter of 1 -> ignore
3 has a counter of 1 -> ignore
Final array:
5 6 4 1 3
There are, of course, more efficient ways to handle the removal (since using an array implies shifting), like inserting the items into a linked list for example. I'll let you decide that. :)
Edit: An even faster approach, requiring a single pass:
Use the same hashing structure as above.
Go through the original array. For each item check the table. If the associated counter is 0, increment it to 1. If it's already 1, remove the item.
I want to reverse an array (or any other data structure) but because this operation is going to be done on the array for n times , im looking for the best solution possible, I have the sorted array , which is gotten in O(nlgn) time , i start looking for first element in the sorted array , inside the unsorted array ( which is equal to finding the smallest key in the unsorted array ) then I reverse the array from the beginning to the index of that value , then i do the same for the rest , find the second smallest value's index , and reverse the array again , from the second index to the end of the array and so on :
for example , consider this array :
*2 6 (*1*) 5 4 *3 // array is reversed from its 0th index to the 3rd index (0 based)
1 *5* 4 3 6 (*2*) // array is reversed from its 1st index (0 based ) to the 5th index
1 2 *6* *3* 4 5 // and ...
1 2 3 *6* *4* 5
1 2 3 4 *6* *5*
1 2 3 4 5 6
well i have to sort the array in order to have the values im looking for in the unsorted array , it'll take o(nlgn) time , and doing the algorithm above , will take o(n^2) ,any idea to make it more quick , to be done in o(nlgn) time ? so the question is reversing a sub array of the array in the least time Order , cause it's done for many times in large sized arrays. ( I can get the indices i and j ( which are the first and last index of the sub array ) in O (n) time cause i have the sorted array and i'll just look up the numbers in the unsorted array ) so im looking for the best time order for reversing an array from it's ith index to it's jth index .
thanks in advance
Here comes an O(n) solution (i think, reading your description was hard). It's a data structure wich allows 1) reversing a sub-array in O(1), 2) Getting a value from the array in O(r), where r is the number of reversings that is done, 3) find the index of an element in O(n), where n is the length of the list.
Just store our array as usual, and have a list of ReversedRange(imin, imax) elements. Reversing part of the array is as easy as inserting another element in this list.
Whenever you need to get a value from the modified array at index i, you look through all the ReversedRange for which imin <= i <= imax, and calculate the index j which corresponds to the original array index. You need to check r reversings, so it is O(r).
To get the index i of a value v, look through the original array and find the index j. Done in O(n) time. Do the same traversing of the ReversedRanges, only in the oppsite direction to calculate i. Done in O(r) time, total O(n+r) which is O(n).
Example
Consider the following list: 0 1 2 3 4 5 6 7 8 9. Now say we reverse the list form indexes 1 through 6, and then from 0 through 5. So we have:
I 0 1 2 3 4 5 6 7 8 9
| |
II 0 6 5 4 3 2 1 7 8 9
| |
III 2 3 4 5 6 0 1 7 8 9
No let us map the index i = 2 to the original array. From the graph we see that we should end up with III(2) = 4
1) since i = 2 is in [0, 5] we calculate
i <- 5 - (i - 0) = 5 - 2 = 3
2) since i = 3 is in [1, 6] we calculate
i <- 6 - (i - 1) = 6 - 2 = 4
3) there are no more ranges, we are done with result 4!
(Possibly) memory heavy...
Why don't you maintain two Collections. Traverse the original collection until you have found your reverse point. Then traverse backwards from there with an iterator or indexing if you have it (ArrayList) adding each element to a new collection. Then merge the two collections (The reversed portion and the previous untouched portion). Repeat this until finished.
Seems like a very simple answer to a complicated question so maybe I'm missing something. If you are looking for an efficient way to reverse part of an array then something like the following should work. You could easily make it generic of course.
// endIndex and startIndex are inclusive here
int half = startIndex + ((endIndex + 1) - startIndex) / 2;
int endCount = endIndex;
for (int startCount = startIndex; startCount < half; startCount++) {
int store = array[startCount];
array[startCount] = array[endCount];
array[endCount] = store;
endCount--;
}
Seems like the rest of your code would be much more complex than this. Not sure what the O() is here because it is not doing comparisons which are traditionally the measure but this is doing 1.5 x N assignments to reverse the array. I don't see any way that this can be done faster.