Sword refers to Offer series Sword refers to Offer 62: the last remaining number in the circle; fights the Joseph ring problem again

Title description:

The n numbers of 0, 1, and n-1 are arranged in a circle, starting from the number 0, and deleting the m-th number from this circle each time. Find the last number remaining in the circle.

For example, the 5 numbers 0, 1, 2, 3, and 4 form a circle. Each time the third number is deleted from the number 0, the first 4 numbers to be deleted are 2, 0, 4, and 1, so at the end The remaining number is 3.

Example 1:

Input: n = 5, m = 3
 Output:  3

Example 2:

Input: n = 10, m = 17
 Output:  2

Problem-solving ideas:

Reversed results according to the law (pictures stolen from leetcode):

First, you need to understand the process of the above picture. That is, the position of the safer at each cycle.

So do you understand the moving position of the deleted number (key)

  1. It can be drawn from the figure: after deleting a number, the whole string of numbers will be divided into two parts, the latter are placed in the front ( moving three digits to the left ), and the front complement is at the back,
    if it is deleted at this time A number, re-added at the end, is just the original array, but the position of the two parts has changed.
  2. So if you are given a sequence at this time, can you reverse the previous sequence?
    That is, if you make up one digit at the end, and then the whole sequence moves three places to the right , then the next few digits will overflow, so again Divide the length of the previous time. Then those who overflowed will go back and restore the way they were before deletion.
  3. So what happens when you bring it to a certain position, its last position is not "(this position + interval length)% last time length" is the last position.
    That is, the position is moved three places to the right this time. If there is no overflow, it means that the last time is behind. If it overflows, it means that the last time was in the front. Then after the last deletion, it moved to the back, so divide by the length to return to the original position.

From this, the process verification of the reverse deduction is obtained:

  • The process of 1->2: the position of (0+3)%2=1
  • The process of 2->3, that is, the position of (1+3)%3=1
  • The process of 3->4, that is, the position of (1+3)%4=0

So this code is very simple, but it is a bit difficult to understand.

Code:

class Solution {
public:
    int lastRemaining(int n, int m) {
        int q=0;
        for(int i=2;i<=n;i++)
        {
            q=(q+m)%i;
        }
        return q;
    }
};

 

Guess you like

Origin blog.csdn.net/qq_46423166/article/details/110817226