[Linked List Problem] Joseph's Problem of Circular Single Linked List

Preface

Update the topic-brushing posts in the form of special topics. Welcome to study topic-brushing with me. Trust me, your persistence will definitely bring unexpected gains. Each question will provide a simple answer, if you have a more elegant approach, welcome to provide guidance, thank you

[Topic description]

[Linked List Problem] Joseph's Problem of Circular Single Linked List

【Claim】

Input: the head node of a circular singly linked list and the reported number m.

Return: The last surviving node, and this node forms a circular singly linked list by itself, and all other nodes are deleted.

【Difficulty】

Taxi: ★☆☆☆

【answer】

Method 1: Time complexity is O( n * m)

This question is quite simple if you don't consider the time complexity. Just traverse the circular linked list, and delete a node every time m nodes are traversed, knowing that only one node is left in the linked list.

code show as below

 1    //时间复杂度为O(n*m)的解决方法
 2    public static Node josephusKill(Node head, int m) {
 3        if(head == null || m < 1)
 4            return head;
 5        Node last = head;
 6        //定位到最后一个节点
 7        while (head.next != last) {
 8            head = head.next;
 9        }
10        int count = 0;
11        while (head.next != head) {
12            if (++count == m) {
13                head.next = head.next.next;
14                count = 0;
15            } else {
16                head = head.next;
17            }
18        }
19        return head;
20    }

As some mobile phones may have garbled characters, I will post pictures here:

[Linked List Problem] Joseph's Problem of Circular Single Linked List
The time complexity of this method is O(n * m). The time complexity is used as a solution below.

Method 2: Time complexity is O(n)

The difficulty of this method is:

School: ★★★☆

We can number the nodes of the circular linked list. If the number of nodes in the linked list is n, start with the head node and sequentially number the nodes, that is, the head node is 1, the next node is 2, and the last node is n.

We use f(n) to denote that when the length of the circular linked list is n, the number of survivors is f(n). Obviously when n = 1, f(n) = 1. If we can find the relationship between f(n) and f(n-1), we can solve it in a recursive way. We assume that the number of people is n, and those who report to m will commit suicide. Then the initial number is

m - 2

m - 1

m

m + 1

m + 2

After one deletion, the node numbered m is deleted. After deletion, there are only n-1 nodes left. The number conversion relationship before and after deletion is:

Before deleting --- After deleting

… --- …

m - 2 --- n - 2

m - 1 --- n - 1

m ---- None (because the number has been deleted)

m + 1 --- 1 (because I will count from here next time)

m + 2 ---- 2

… ---- …

There are only n-1 nodes in the new ring. And the nodes numbered m + 1, m + 2, m + 3 become the nodes numbered 1, 2, 3 in the new ring.

Assuming old is the node number before deletion, and new is the number after deleting a node, the relationship between old and new is old = (new + m-1)% n + 1.

Note: Some people may wonder why it is not old = (new + m)% n? Mainly because the numbering starts from 1, not from 0. If new + m == n, the final calculation result will be old = 0. So old = (new + m-1)% n + 1.

In this way, we get the relationship between f(n) and f(n-1), and f(1) = 1. So we can do it in a recursive way.

code show as below:

 1   //时间复杂度为O(n)
 2    public static Node josephusKill2(Node head, int m) {
 3        if(head == null || m < 1)
 4            return head;
 5        int n = 1;//统计一共有多少个节点
 6        Node last = head;
 7        while (last.next != head) {
 8            n++;
 9            last = last.next;
10        }
11        //直接用递归算出目的编号
12        int des = f(n, m);
13        //把目的节点取出来
14        while (--des != 0) {
15            head = head.next;
16        }
17        head.next = head;
18        return head;
19    }
20
21    private static int f(int n, int m) {
22        if (n == 1) {
23            return 1;
24        }
25        return (f(n - 1, m) + m - 1) % n + 1;
26    }

Picture code:

[Linked List Problem] Joseph's Problem of Circular Single Linked List

Problem expansion

For the previous question, suppose it is to delete the number from the Kth node? How to solve it?

answer

Backstage reply answer 3 get answer

Past

[Linked list problem] Delete the intermediate node of a singly linked list

[Linked list problem] How to elegantly reverse a singly linked list

[Linked list problem] Delete the Kth node in the singly linked list

[Algorithm combat] Generate window maximum array
[Linked List Problem] Joseph's Problem of Circular Single Linked List

Guess you like

Origin blog.51cto.com/15015171/2555344