18th questions (array ):
Question: N numbers (0, 1 ,..., N-1) Form a circle, starting from the number 0,
Delete the MTH number from this circle each time (the first is the current number itself, and the second is the next of the current number)
Number ). After a number is deleted, the M number is deleted from the next one.
Find the remaining number in the circle.
Idea: Intuition is not difficult to see this question. Just simulate the process. I use an array to represent the number of the current first number. If a number is deleted, the subsequent number is moved to the front.
/* 18th question (array): Question: N numbers (0, 1 ,..., N-1) to form a circle, starting from the number 0, each time from this circle to delete the M number (the first is the current number itself, the second is the next number of the current number ). After a number is deleted, the M number is deleted from the next one. Find the remaining number in the circle. Start time = 10: 38end time = 11: 30 */# include <stdio. h> # include <stdlib. h> # include <string. h> int findlast (int * n, int Len, int M, int first) // n is the array of input numbers Len is the length of the input number M is to delete the first number first is the first number is the number {If (LEN = 1) {return N [0];} else {int d = (M % Len) + first-1; for (INT I = d-1; I <len-1; I ++) {n [I] = N [I + 1];} return findlast (n, len-1, m, d % (LEN-1 ));}} int findlastn (int n, int m) {int * num = (int *) malloc (sizeof (INT) * n); For (INT I = 0; I <N; I ++) {num [I] = I;} return findlast (Num, n, m, 1);} int main () {int ans = findlastn (5, 7); Return 0 ;}
Find the answer online and find that this is a classic problem, Joseph ring. There are two common methods: Simulated O (Mn) and mathematical O (n.
Loop linked lists are used for online simulation:
Source http://www.cnblogs.com/dartagnan/archive/2011/09/16/2179143.html
int LastRemaining_Solution1(unsigned int n, unsigned int m) { // invalid input if(n < 1 || m < 1) return -1; unsigned int i = 0; // initiate a list with n integers (0, 1, ... n - 1) list<int> integers; for(i = 0; i < n; ++ i) integers.push_back(i); list<int>::iterator curinteger = integers.begin(); while(integers.size() > 1) { // find the mth integer. Note that std::list is not a circle // so we should handle it manually for(int i = 1; i < m; ++ i) { curinteger ++; if(curinteger == integers.end()) curinteger = integers.begin(); } // remove the mth integer. Note that std::list is not a circle // so we should handle it manually list<int>::iterator nextinteger = ++ curinteger; if(nextinteger == integers.end()) nextinteger = integers.begin(); -- curinteger; integers.erase(curinteger); curinteger = nextinteger; } return *(curinteger); } ///////////////////////////////////////////////////////////////////////// n integers (0, 1, ... n - 1) form a circle. Remove the mth from // the circle at every time. Find the last number remaining // Input: n - the number of integers in the circle initially// m - remove the mth number at every time// Output: the last number remaining when the input is valid,// otherwise -1///////////////////////////////////////////////////////////////////////int LastRemaining_Solution1(unsigned int n, unsigned int m){ // invalid input if(n < 1 || m < 1) return -1; unsigned int i = 0; // initiate a list with n integers (0, 1, ... n - 1) list<int> integers; for(i = 0; i < n; ++ i) integers.push_back(i); list<int>::iterator curinteger = integers.begin(); while(integers.size() > 1) { // find the mth integer. Note that std::list is not a circle // so we should handle it manually for(int i = 1; i < m; ++ i) { curinteger ++; if(curinteger == integers.end()) curinteger = integers.begin(); } // remove the mth integer. Note that std::list is not a circle // so we should handle it manually list<int>::iterator nextinteger = ++ curinteger; if(nextinteger == integers.end()) nextinteger = integers.begin(); -- curinteger; integers.erase(curinteger); curinteger = nextinteger; } return *(curinteger);}
The mathematical methods are enlightening and pushed forward from the back. Push back the remaining numbers to the initial values in sequence.
Process http://www.360doc.com/content/12/0314/13/1429048_194255548.shtml
Code: http://www.cnblogs.com/dartagnan/archive/2011/09/16/2179143.html
int LastRemaining_Solution2(int n, unsigned int m) { // invalid input if(n <= 0 || m < 0) return -1; // if there are only one integer in the circle initially, // of course the last remaining one is 0 int lastinteger = 0; // find the last remaining one in the circle with n integers for (int i = 2; i <= n; i ++) lastinteger = (lastinteger + m) % i; return lastinteger; }