- There are n bottles of powder. One bottle is toxic. When toxic powder is melted into the water for an hour, the water becomes blue. You have some test tubes. how long and how many test tubes are required to determine the toxic powder? The time when the powder is imported into the test tube is not considered.
The most basic idea of this question is to change the time for space or space for time, that is, to test n test tubes in one hour or N hours in sequence. In actual production, it should be biased towards changing the space time, because hard resources can be increased, and if the program cannot find a good optimization method, the running time is basically determined, so the time is more important than the space. But neither of them is a good solution. Another better solution is to divide the bottle into two groups. It takes an hour to exclude half of the bottle and an hour to exclude the remaining half of the bottle .... because the solution after each hour has been verified and can be reversed, the test tube can be reused, so the result is one test tube, and log2 (n) is rounded up. However, a long wait is obviously not good. It is better to sacrifice space to save time. Therefore, we can speed up the judgment by three or four or n minutes, but to this extent, at last it became n-1 test tubes and one hour ......
There was no particular idea at the beginning of this question. Later I came up with a wonderful solution: it only took 1 hour and only needed log (n + 1) the number of test tubes rounded up. In this way, the time is already the shortest time, and the space should also be the shortest space.
All bottles from 1 ~ N number: place the log (n + 1) to an integer. The number of test tubes is rounded up. The value from right to left indicates the low position to the high position. All the powder numbers are converted to binary, pour them into the corresponding test tubes. An hour later, the change of the Blue test tube is 1, and the change of the Blue test tube is 0. This binary sequence is converted into a 10-digit System, which is the serial number of the toxic powder. For example, 10 bottles of powder, found that 2nd and 3rd tubes turn blue, that is, 0110, obviously 6 bottles are toxic powder. This solution seems to be able to continue to be optimized. Before that, we considered starting from 1 because we felt that all powders should be involved in the experiment, and it seemed unnecessary. The number can start from 0. If there is no blue in the test tube, the unused bottle 0 is a poison bottle, which sometimes saves a test tube.
So the final answer: 1 hour time, log (n) to take the whole test tube number, that is, the binary number of the N-1. 1000 bottles of powder only need 10 tubes and one hour ~
- Given a single-chain table without loops, how can we quickly locate the node in the center of the linked list? The returned value is a pointer to the intermediate node.
Let's first look at the simple algorithm: first we need to traverse the entire linked list, calculate the number of nodes N, and then traverse the chain table n/2 times again, so that we can find the node in the middle, this is the time complexity of O (N), with an integer variable representing n. The pointer is moved N + n/2 times, and the first time it is passed over the integer variable + + n times.
I thought of a better way: Just two pointers, just traverse once.
The two pointers first point to the header, then the first pointer takes two steps at a time, and the second pointer takes one step at a time. Because there is no ring, when the first pointer reaches the end, the second pointer is naturally in the middle.
PS: The following is my concise code. Is there any more concise code?
node* find(node *head){ node *s = head, *t = head; while(t = t->next) { s = s->next; if((t = t->next) == NULL) break; } return s;}
The complete test code is as follows:
# Include <iostream> using namespace STD; struct node {int val; node * Next;}; void createlinklist (node * linklist) {node * s = linklist; for (INT I = 0; I <10; I ++) {node * t = new node; t-> val = I; t-> next = NULL; S = s-> next = T;} void showlinklist (node * linklist) {node * s = linklist-> next; while (S = s-> next) printf ("% d", S-> Val); putchar (10);} node * Find (node * head) {node * s = head, * t = head; while (t = T-> next) {S = s-> next; If (t = T-> next) = NULL) break;} return s ;} int main () {node * linklist = new node; createlinklist (linklist); showlinklist (linklist); node * Re = find (linklist-> next ); // The input parameter is the first valid node printf ("mid: % d \ n", re-> Val); getchar (); Return 0 ;}