1. 程式人生 > 其它 >劍指offer 15、反轉連結串列 python c++

劍指offer 15、反轉連結串列 python c++

題目描述:

輸入一個連結串列,反轉連結串列後,輸出新連結串列的表頭。

思路:看程式碼註釋,講的應該還算清楚。主要做法就是從前往後,每次用到三個節點,1、原始的第一個節點p1(整個過程中始終不變),2、本次要放到最前面的節點p2,3、下一次要放到最前面的節點p3(其實就是p2.next),

每次完成一個節點的倒序,舉個例子原來是 1 2 3 4 5 ,第一次結束後變成 2 1 3 4 5 ,再一次變成 3 2 1 4 5

那麼其實我們就有一個大概的步驟了:

1、把1的下一個指向3, 含義是把第一個節點的next指向 下一次要放到最前面的節點p3
2、把2的下一個指向1,含義是把本次要放到最前面的節點p2的next指向上一次變化後的最開始節點
3、把第一個變成2,含義是把本次要放到最前面的節點p2放到最開始

我們再來模擬一下第二次變化的過程:

1、把第一個節點的next指向 下一次要放到最前面的節點p3 , 就是把1(第一個節點)的下一個指向4( 下一次要放到最前面的節點)
2、把本次要放到最前面的節點p2的next指向原來的最開始節點,把3(本次要放到最前面的節點)的下一個指向2(上一次變化後的最開始節點)
3、把本次要放到最前面的節點p2放到最開始,即把3(本次要放到最前面的節點)放到最開始

3—>2—>1—>4—>5紅色的是我們改變的指向關係,3是我們本次要放到最前面的節點

接著迴圈,4 3 2 1 55 4 3 2 1 ,直到我們下一個要放到前面的節點是空,意味著我們的倒序結束了,已經完成

python 版

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):   
        # write code here
        if pHead == None or pHead.next == None:   #排除沒有元素和只有一個元素
            return pHead
       #python裡面居然head就是第一個節點,見鬼了
        p1 = pHead   #代表原始的第一個節點
        p2 = p1.next    #代表要放到最前面(head後面)的節點
        p3 = None   #這兒不等於p2.next是因為怕只有兩個元素 ,它的含義是代表下一個放到最前面(head後面)的節點,
        while p2 != None:
            p3 = p2.next   #找到下一個放到最前面的節點,
            p1.next = p3   #第一個節點的後續節點指向下一個要放到最前面節點p3
            p2.next = pHead    #本次要節點p2放到最前面,那麼原來的最前面就變成本次要放到最前面節點p2的後續節點
            pHead = p2   #頭結點的後續節點指向本次要放到最前面節點p2
             # 這樣一來,p3前面的節點都是倒序了的
            p2 = p3  #然後把p3賦值給p2,進行下一次迴圈
        return pHead

c++版

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead == nullptr || pHead->next == nullptr){
            return pHead;
        }
        ListNode *p1 = pHead;
        ListNode *p2 = p1->next;
        ListNode *p3 = nullptr;
        while(p2 != nullptr){
            p3 = p2->next;
            p1->next = p3;
            p2->next = pHead;
            pHead = p2;
            p2 = p3;
        }
        return pHead;
    }
};

c++ 版翻車版

翻車原因,這次的連結串列是沒有頭結點的。牛客網就是這個比較煩,不說清楚。

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead->next == nullptr || pHead->next->next == nullptr){
            return pHead;
        }
        ListNode *p1 = pHead->next;
        ListNode *p2 = p1->next;
        ListNode *p3 = nullptr;
        while(p2 != nullptr){
            p3 = p2->next;
            p1->next = p3;
            p2->next = pHead->next;
            pHead->next = p2;
            p2 = p3;
        }
        return pHead;
    }
};