title : 0,1,..., n-1 This n number of words in a circle, starting with the number 0 each time you remove the number m from this circle. Find the last number left in this circle. (Joseph Ring question)
Method 1: Simulate with a ring list (std::list), whenever an iterator (Iterator) is scanned to the end of the list, move the iterator to the head of the list, which is equivalent to traversing through a circle in order. Time Complexity O (MN), Spatial complexity O (n).
int lastremaining (unsigned int n, unsigned int m) {if (N < 1 | | m < 1) {return
-1;
} unsigned int i = 0;
List<int> numbers;
for (i = 0; i < n; ++i) {numbers.push_back (i);
} list<int>::iterator current = Numbers.begin ();
while (Numbers.size () > 1) {for (int i = 1; i < m; ++i) {current++;
if (current = = Numbers.end ()) {current = Numbers.begin ();
}} List<int>::iterator next = ++current;
if (next = = Numbers.end ()) {next = Numbers.begin ();
}--current;
Numbers.erase (current);
current = next;
} return * (current); }
Method 2: Use a recursive relationship. Time complexity O (n), Spatial complexity O (1)
F (n,m) ={0,[f (n−1,m) +m]%n,ifnifn=1,>1. \begin{equation} \notag F (n,m) = \left\{\begin{aligned} &0,&if\;n &= 1,\\ &[f (n-1,m) +m]\%n,&if\;n&>1. \end{aligned} \right. \end{equation}
int lastremaining (unsigned int n, unsigned int m) {
if (N < 1 | | m < 1) {
return-1;
}
int last = 0;
for (int i = 2, I <= N; i++) {Last
= (last + m)% i;
}
return last;
}
test Case : Functional test (input m less than n, such as from the first 5-digit circle to delete each 2nd, 3 digits; the input m is greater than or equal to n, such as removing each 6th, 7 digits from the first 6-digit circle) special input test (0 digits in the circle) Performance test (remove the No. 997 number each time from a circle that initially has 4,000 digits)