There are N children standing in a line. Each child is assigned a rating value.
You are giving candies to these children subjected to the following requirements:
Each child must have at least one candy.
Children with a higher rating get more candies than anybody with lower.
What is the minimum candies you must give?
Example:
Input:
[2, 1, 5]
Output:
6
Complexity: O(n)
There are already many solutions for this task when we notice only neighboring children (ex: https://leetcode.com/problems/candy/solution/) but what to do with this case?
Related
Could you, please, help me with the data structure that allows O(logN) (or at least O(sqrtN)) operations for the following:
Insert an item having ID (int64_t) and health (double)
Remove an item by ID
Find an item that is weighted random by health
The preferred language is C++ or C. By the weighted random I mean the following:
Consider totalHealth=Sum(health[0], health[1], ..., health[N-1]). I need a fast (as described above) operation that is equivalent to:
Compute const double atHealth = rand_uint64_t()*totalHealth/numeric_limits<uint64_t>::max();
Iterate over i=0 to N-1 to find the first i such that Sum(health[0], health[1], ..., health[i]) >= atHealth
Constraints: health[i] > 0, rand_uint64_t() returns a uniformly distributed integer value between 0 and numeric_limits<uint64_t>::max().
What I have tried so far is a C++ unordered_map that allows quick (Θ(1)) insertion by ID and removal by ID, but the operation #3 is still linear in N as described in my pseudo-code above.
You help is very appreciated!
I can't think of a way to do it with the existing STL containers but I can think of a way to do it if you're willing to code up your own binary tree. The trick is that each node maintains the total health of all the nodes to its left (it doesn't need to worry about nodes to its right as you'll see below). Then, if you walk the tree in ID order you can also compute the "cumulative health", also in ID order, in log(n) time. So the tree is sorted by both ID and cumulative health and you can do lookups in log(n) time either by ID or by "cumulative health". For example, consider a very simple tree like the following:
ID: 8
h: 10
chl: 15
+-------|--------+
| |
ID: 4 ID: 10
h: 15 h: 7
chl: 0 chl: 0
in the above h is the health of the node and chl is the cumulative health of all nodes to it's left. So the total health of all nodes in the above is 15 + 10 + 7 = 32 (and I assume you maintain that count separately though you could also track cumulative health of nodes the right and you wouldn't need to). Let's look at 3 cases:
You compute an atHealth < 15. Then at the first node you can see that your value is less than the chl so you know you need to go left and you end up at the correct leaf.
You compute an atHealth >= 15 < 25 so you know it's > 15 so you don't go left at the root, the node you're at has health 10 and 10 + 15 means the cumulative health at that node is between 15 and 25 so you're good.
You compute an atHealth >= 25. Every time you visit a node and go right you must add the chl and h of the node you were at to keep computing cumulative health as you walk the tree so you know you're starting at 10 + 25 = 25 when you go right and you'll add that to the h or chl of any node you encounter after that. Thus you can quickly find that the node to the right is the correct one.
When you insert a new node you increment the total health of each parent node as you walk the tree and when you remove a node you walk back up the tree subtracting from the total health. Inserts and deletions are thus still O(log(n)) and lookups by ID are also log(n) either by ID or by atHealth.
Things obviously get more complicated if you want to maintain a balanced tree but it's still do-able.
I was solving a question on Hackerrank. The following is the question (in brief):
There exist n robbers trying to rob a bank. They can stay there for atmost G minutes. Only two robbers can enter a vault at a time.
a[]={a_1,a_2,...,a_n} is a user specified array such that a_i is the time the i_th robber wishes to stay in the vault.
A heist is successful if all the robbers get their wish.
Given n,G, a[]; the output must be "success" or "failure".
My logic was as follows:
sort(a) in descending order
define slot1 and slot2 for 1st and 2nd person in vault respectively
slot1=slot2=G
fill in slot1 and slot2 from the sorted a, such that whenever a robber is finished in the slot, the next one takes his place
If all robbers can be accommodated, then success, else failure.
I would try having a double pass. First, add up all the time the robbers would want, then halve and round up. That's your ideal time. (at this point, check if one of your robbers is at/over this amount; if so, then that's your limit.) Then, try to fit robbers into that time frame. If you can fit them evenly, you're good. Otherwise, increase the time and try again.
Edit: As JonTheMon noted above, your approach would fail when G = 6 and a = {2, 2, 2, 3, 3}.
Anyway, your idea is wrong and you would not be able to solve the problem in such a way. Here is a hint:
This is a classical DP problem.
old post with wrong test case:
Let G = 4 and a[] = {1, 2, 2, 3}.
As far as I understood your approach, you will first accommodate robbers a_1 and a_2. After a_1 finished, you will introduce a_3 on his place. However, this leaves a_4 without enough time in a vault - only 2 minutes where he wanted to be inside at least 3.
This question already has answers here:
How to code the maximum set packing algorithm?
(2 answers)
Closed 8 years ago.
Given N different candies and M children. Each of the children demands for K[i] different candies and will only be happy iff he get all those different candies which he demanded.
Now I want to maximize the number children that get happy. How should I distribute the candies?
Example: Let's have N=4 candies and M=3 children:
1st child requires 2 (K[1]) candies which are: 1 and 2
2nd child requires 2 (K[2]) candies which are: 2 and 3
3rd child requires 2 (K[3]) candies which are: 3 and 4
The answer here is 2 as I can at best only make the 1st and 3rd child happy.
My attempt:
Give candies to children in the order of the amounts that they require to be happy (i.e. K[i]). In other words, you should only give candy to a child if you have made happy all the children that demand less, and every time you give candy to one of them you have to give them the whole amount that they require.
Is this solution correct?
Yes, you are wrong. Consider:
Wants candies 1, 2, 3, and 4.
Wants candies 1, 5, 6, 7, 8, and 9.
Wants candies 2, 10, 11, 12, 13, 14, and 15.
Wants candies 3, 16, 17, 18, 19, 20, and 21.
Wants candies 4, 22, 23, 24, 25, 26, and 27.
Your algorithm will only make child 1 happy. But you can make 2, 3, 4, and 5 happy.
As this a problem in on-going programming contest i cannot give you much of an answer but will push you in right direction. The problem you are solving is np complete as it can be reduced to maximum independent set and hence it can only be solved in general case using brute force which is trying out all combinations. You can reduce computations by checking if new set added is not intersecting with the other in this way you can skip a lot of invalid combinations.
I'm a real speed freak if it gets to algorithms, and in the plugins I made for a game.
The speed is.. a bit.. not satisfying. Especially while driving around with a car and you do not follow your path, the path has to be recalculated.. and it takes some time, So the in-game GPS is stacking up many "wrong way" signals (and stacking up the signals means more calculations afterward, for each wrong way move) because I want a fast, live-gps system which updates constantly.
I changed the old algorithm (some simple dijkstra implementation) to boost::dijkstra's to calculate a path from node A to node B
(total node list is around ~15k nodes with ~40k connections, for curious people here is the map: http://gz.pxf24.pl/downloads/prv2.jpg (12 MB), edges in the red lines are the nodes),
but it didn't really increase in speed. (At least not noticeably, maybe 50 ms).
The information that is stored in the Node array is:
The ID of the Node,
The position of the node,
All the connections to the node (and which way it is connected to the other nodes, TO, FROM, or BOTH)
Distance to the connected nodes.
I'm curious if anybody knows some faster alternatives in C/C++?
Any suggestions (+ code examples?) are appreciated!
If anyone is interested in the project, here it is (source+binaries):
https://gpb.googlecode.com/files/RouteConnector_177.zip
In this video you can see what the gps-system is like:
http://www.youtu.be/xsIhArstyU8
as you can see the red route is updating slowly (well, for us - gamers - it is slow).
( ByTheWay: the gaps between the red lines have been fixed a long time ago :p )
Since this is a GPS, it must have a fixed destination. Instead of computing the path from your current node to the destination each time you change the current node, you can instead find the shortest paths from your destination to all the nodes: just run Dijkstra once starting from the destination. This will take about as long as an update takes right now.
Then, in each node, keep prev = the node previous to this on the shortest path to this node (from your destination). You update this as you compute the shortest paths. Or you can use a prev[] array outside of the nodes - basically whatever method you are using to reconstruct the path now should still work.
When moving your car, your path is given by currentNode.prev -> currentNode.prev.prev -> ....
This will solve the update lag and keep your path optimal, but you'll still have a slight lag when entering your destination.
You should consider this approach even if you plan on using A* or other heuristics that do not always give the optimal answer, at least if you still get lag with those approaches.
For example, if you have this graph:
1 - 2 cost 3
1 - 3 cost 4
2 - 4 cost 1
3 - 4 cost 2
3 - 5 cost 5
The prev array would look like this (computed when you compute the distances d[]):
1 2 3 4 5
prev = 1 1 1 2 3
Meaning:
shortest path FROM TO
1 2 = prev[2], 2 = 1, 3
1 3 = prev[3], 3 = 1, 3
1 4 = prev[ prev[4] ], prev[4], 4 = 1, 2, 4 (fill in right to left)
1 5 = prev[ prev[5] ], prev[5], 5 = 1, 3, 5
etc.
To make the start instant, you can cheat in the following way.
Have a fairly small set of "major thoroughfare nodes". For each node define its "neighborhood" (all nodes within a certain distance). Store the shortest routes from every major thoroughfare node to every other one. Store the shortest routes to/from each node to its major thoroughfares.
If the two nodes are in the same neighborhood you can calculate the best answer on the fly. Else consider only routes of the form, "here to major thoroughfare node near me to major thoroughfare near it to it". Since you've already precalculated those, and have a limited number of combinations, you should very quickly be able to calculate a route on the fly.
Then the challenge becomes picking a set of major thoroughfare nodes. It should be a fairly small set of nodes that most good routes should go through - so pick a node every so often along major streets. A list of a couple of hundred should be more than good enough for your map.
Given a linked list of T size , select first 2n nodes and delete first n nodes from them; Then do it for the next 2n nodes and so on...
For example-
Let's consider a linked list of size 7:
`1->2->3->4->5->6->7`
If n = 2, the desired output is :
`1->2->5->6->7`
I didn't understand what this problem is actually indicating.Could somebody help me to understand the problem ?
EDIT : Adding C and C++ tags so that this may reach to more eye balls, and of-course those are only two languages allowed in the interview itself.
That actually looks like it should say:
Given a linked list of T size , select first 2n nodes and delete last n nodes from them; Then do it for the next 2n nodes and so on...
or:
Given a linked list of T size , select first 2n nodes and keep first n nodes from them; Then do it for the next 2n nodes and so on...
That would mean select 1,2,3,4 then delete 3,4 (or keep 1,2 which is the same thing). Then select 5,6,7,8, not possible so stop.
I think it's even simpler than #paxdiablo indicates ...
do
take n
skip n
until you run out of elements to take or skip