Interview must: Detailed explanation of divide-and-conquer algorithm (with python tower of Hanoi case implementation)

Principle of divide and conquer algorithm:

Divide -decompose the problem into smaller sub-problems;
cure -break these smaller sub-problems one by one;
combine -merge the solved sub-problems to finally get the solution of the "parent" problem;

In the specific operation of the divide and conquer method, there are mainly the following two steps:

1. Find the most primitive operation. This operation must be as simple as possible.
(Such as the initial plate of the Tower of Hanoi, move one plate directly from the first pillar to the third pillar)
—————————————————————— ——————————
2. Determine how to reduce the scale of the problem, and then continue to decompose (or reduce the scale) of the problem until it meets the most primitive operation.
(For example, the Tower of Hanoi problem is decomposed into two plates moving 1, n-1, and then recursively iteratively solve them one by one)

Typical example
questions : 1. Likou Interview Question 08.06. Tower of Hanoi Question: https://blog.csdn.net/weixin_44414948/article/details/114272156

Examples of the classic Tower of Hanoi:

Interview Question 08.06. The Tower of Hanoi Question

In the classic Tower of Hanoi problem, there are 3 pillars and N perforated discs of different sizes, and the plate can slide into any pillar. At the beginning, all the plates are placed on the first pillar in ascending order from top to bottom (that is, each plate can only be placed on a larger plate). The following restrictions apply when moving the disc:
(1) Only one plate can be moved at a time;
(2) The plate can only slide from the top of the column to the next column;
(3) The plate can only be stacked on a plate larger than it on.
Insert picture description here
Please write a program to use the stack to move all the plates from the first pillar to the last pillar.

You need to modify the stack in place.

Example 1:

Input: A = [2, 1, 0], B = [], C = []
Output: C = [2, 1, 0]

Example 2:

Input: A = [1, 0], B = [], C = []
Output: C = [1, 0]

prompt:

The number of plates in A is not more than 14.

Problem solution ideas:

Recursion and Divide and Conquer
This is a classic topic of recursive methods, it is quite difficult to sort out the clues at first thought, we might as well start with the simple ones.
(1)

Assuming n = 1, there is only one plate, it is very simple, just take it out of A and move it to C;

(2)

What if n = 2? At this time we have to use B, because the small plate must always be on top of the large plate, a total of 4 steps are required.
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here

(3)

What if n> 2? The idea is the same as the above. We also regard n plates as two parts, one part has 1 plate and the other part has n-1 plates.
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here

Looking at the picture above, you may ask: "How did n-1 plates move from A to C?"

Note that when you are thinking about this problem, the problem of moving the first n plates from A to C is transformed into the problem of moving n-1 plates from A to C , and so on, until it becomes 1 The problem is solved when the problem is with a plate. This is the idea of divide and conquer .

The common way to realize the idea of ​​divide and conquer is recursion. It is not difficult to find that if the original problem can be decomposed into several smaller sub-problems with the same structure as the original problem, it can often be solved by recursive methods. The specific solutions are as follows:

When n = 1, directly move the plate from A to C;
——————————————————————————————————
n> 1:00:
1. First move the above n-1 plates from A to B (sub-problem, recursion);
2. Then move the largest plate from A to C;
3. Then move n-1 plates on B from B moves to C (subproblem, recursion).

Problem solution python code:

class Solution:
    def hanota(self, A: List[int], B: List[int], C: List[int]) -> None:
        n = len(A)
        self.move(n, A, B, C)
    # 定义move 函数移动汉诺塔
    def move(self,n, A, B, C):
        if n == 1:
            C.append(A[-1])
            A.pop()
            return 
        else:
            self.move(n-1, A, C, B)  # 将A上面n-1个通过C移到B
            C.append(A[-1])          # 将A最后一个移到C
            A.pop()                  # 这时,A空了
            self.move(n-1,B, A, C)   # 将B上面n-1个通过空的A移到C

Complexity analysis:
Time complexity: O(2^n-1). The total number of moves required.
Space complexity: O(1).

Insert picture description here

Reference source: https://leetcode-cn.com/problems/hanota-lcci/solution/tu-jie-yi-nuo-ta-de-gu-shi-ju-shuo-dang-64ge-pan-z/

Guess you like

Origin blog.csdn.net/weixin_44414948/article/details/114272433