You have a linked-list of linked-lists. We can call the high-level linked-list a Box, and each sub-linked-lists an Item. A Box will, of course, have one or more of Items in them. Each box has a bunch of items in it (nodes) that have a weight. A box has a total weight.
For safety reasons, all boxes' weights must be as close to each other as possible. Basically, the heaviest box and the lightest box should be as small as possible. Your task is to "balance" the boxes' weights. You do have some constrains though:
- Items in a box (the nodes) can only be moved if they are a
heador atail. - The head of a box can only move to the "previous" box, and becomes the "previous" box's tail. The new tail, or old head, has no reference to the items in the box from whence it came. You basically reset the node's connections, then link it to the "previous" box in such a way that it becomes the tail.
- The tail of a box can only move to the next box, and becomes it's head, in a similar fashion to the explanation above.
- Each box has a maximum weight (you can assume that each box is already under that maximum weight).
- You can "delete" boxes if you move all the items out.
- You cannot create boxes.
- Boxes can have as many items in them as long as the box is not above the max weight. A box cannot have 0 items though.
So, take this example, where each box has a maximum weight of 15:
| Box1 Box2 Box3 |
| ----------- ----------- --- |
| | 3<->4<->5 | <--> | 4<->4<->6 | <--> | 1 | |
| ----------- ----------- --- |
Box1 has a total weight of 12, Box2 14, and Box3 1. In a perfect world, you would move Box3's head/tail to Box1, but you cannot do that because Box3 is not "connected" to Box1. You can only "shift" items, basically, in one step, in a forward or backward direction.
So, the best move is to shift box3's head to box2, and make it the new tail, so:
| Box1 Box2 |
| ----------- -------------- |
| | 3<->4<->5 | <--> | 4<->4<->6<->1| |
| ----------- -------------- |
Now, you have the differences between the totals as 3. You cant do any better.
How would you do this in the best way possible?
You can assume this is what your "classes" looks like:
class Box:
item: Item
next: Box
prev: Box
class Item:
weight: int
next: Item
prev: Item
Edit:
Someone asked what you would do if you had an extra number in Box3 such that it would look like this:
| Box1 Box2 Box3 |
| ----------- ----------- ------- |
| | 3<->4<->5 | <--> | 4<->4<->6 | <--> | 1<->2 | |
| ----------- ----------- ------- |
The weight between the heaviest and lightest boxes is 14 - 3, which is 11.
You could do two things here:
- You can move
1fromBox3toBox2. This would make the difference 13, which is an increase from the previous 11. So, not a good idea. - You could move
6from box2 to Box3, so you would have the difference between the the heaviest box (box1) and the lightest box (box2) 4. That is better than what you have now.
| Box1 Box2 Box3 |
| ----------- ------- ----------- |
| | 3<->4<->5 | <--> | 4<->4 | <--> | 6<->1<->2 | |
| ----------- ------- ----------- |
Edit 2:
A commenter asked what if you had this situation, but with a max weight of 17?:
| Box1 Box2 Box3 |
| ----------- ----------- ------- |
| | 3<->4<->5 | <--> | 4<->4<->6 | <--> | 1<->2 | |
| ----------- ----------- ------- |
In this situation, box1: 12, box2: 14, box3: 3. It would seem best to move all of box3's contents into box 2, then move the head of box2 into box1, so:
| Box1 Box2 Box3 |
| ----------- --------------- --- |
| | 3<->4<->5 | <--> | 4<->4<->6<->1 | <--> | 2 | |
| ----------- --------------- --- |
Then:
| Box1 Box2 |
| ----------- ------------------- |
| | 3<->4<->5 | <--> | 4<->4<->6<->1<->2 | |
| ----------- ------------------- |
Now, box1: 12, box2: 17, which is a difference of 5.
You could improve this by moving the 4 in box2:
| Box1 Box2 |
| --------------- --------------- |
| | 3<->4<->5<->4 | <--> | 4<->6<->1<->2 | |
| --------------- --------------- |
Now, box1: 16, box2: 13, which is a difference of 3.