Programmer interview questions (14): the last number left in the circle

Source: Internet
Author: User
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. Analysis: Since the question has a digital circle, it is natural that we use a Data Structure to simulate this circle. In common data structures, we can easily use a Circular List. We can create a ring list with a total of M numbers, and then delete the MTH element from this list each time. In reference code, we use STD: List in STL to simulate this Circular List. Because the list is not a circular structure, remember to move the drop agent to the header of the list every time the drop agent scans the end of the list. In this way, the list is traversed in the order of a circle. This idea requires a ring list with N nodes to simulate the deletion process, so the memory overhead is O (n ). In addition, This method requires M-step operations for each number to be deleted. There are n numbers in total, so the total time complexity is O (Mn ). When M and N are both large, this method is very slow. Next we will try to analyze some laws in mathematics. First, define the first n numbers (0, 1 ,..., N-1), the last number left is F (n, m) for the N and M equations ). In the N numbers, the first number to be deleted is M % n-1, which is recorded as K for simplicity. Then the number of N-1 after K is deleted is 0, 1 ,..., K-1, k + 1 ,..., N-1, And the number starting to count next is k + 1. It is equivalent to sorting k + 1 to the top of the remaining sequence to form the sequence k + 1 ,..., N-1, 0 ,... K-1. The remaining number of the sequence should also be about N and M functions. Because the rule of this sequence is different from the previous sequence (the original sequence is a continuous sequence starting from 0), this function is different from the previous function, which is marked as f' (n-1, m ). The number F (n, m) at the end of the initial sequence must be the number f' (n-1, m) at the end of the sequence, so f (n, m) = f' (n-1, m ). Next we will take the rest of the n-1 Number Sequence k + 1 ,..., N-1, 0 ,... K-1 as a ing, the result of the ing is a sequence from 0 to N-2: k + 1-> 0
K + 2-> 1
...
N-1-1> n-k-2
0> n-k-1
...
K-1-> N-2 defines the ing as p, p (x) = (x-k-1) % N, that is, if the number before the ing is X, the number after the ing is (x-k-1) % N. The corresponding inverse ing is 1 (x) = (x + k + 1) % N. Because the mapped sequence is in the same form as the original sequence, it is a continuous sequence starting from 0. Therefore, we can still use the function f to represent it as F (n-1, m ). According to our ing rules, the number f' (n-1, m) = p-1 [F (n-1, m)] = [F (n-1, m) + k + 1] % N. After K = m % N-1 is substituted, F (n, m) = f' (n-1, m) = [F (n-1, m) + M] % N is obtained. After the above complex analysis, we finally found a recursive formula. To get the last and remaining digits of the sequence of N numbers, you only need to get the last and remaining digits of the sequence of n-1 numbers, and so on. When n = 1, that is, there is only one digit 0 in the sequence, then it is clear that the last number is 0. We represent this relationship as: 0 n = 1
F (n, m) = {
[F (n-1, m) + M] % N n> 1 Although the analysis process of this formula is very complex, it is easy to implement with recursion or loops. The most important thing is that this is a method with the time complexity O (N) and the space complexity O (1). Therefore, it is better than the previous idea in terms of time and space. Reference code for IDEA 1: //////////////////////////////////////// ///////////////////////////////
// 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 shoshould 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 shoshould handle it manually
List <int>: iterator nextinteger = ++ curinteger;
If (nextinteger = integers. End ())
Nextinteger = integers. Begin ();

-- Curinteger;
Integers. Erase (curinteger );
Curinteger = nextinteger;
}

Return * (curinteger );
} Reference code for idea 2: //////////////////////////////////////// ///////////////////////////////
// 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_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;
} If you are interested in the time complexity of the two ideas, you can set the values of N and m to a slightly larger value, such as a number of magnitude 100,000, when running, you can obviously feel that the time efficiency of the code written by these two ideas is very different.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.