題目描述:
https://leetcode.cn/problems/reverse-linked-list-ii
給你單連結串列的頭指標 head
和兩個整數 left
和 right
,其中 left <= right
。請你反轉從位置 left
到位置 right
的連結串列節點,返回 反轉後的連結串列 。
示例 1:
輸入:head = [1,2,3,4,5], left = 2, right = 4 輸出:[1,4,3,2,5]
示例 2:
輸入:head = [5], left = 1, right = 1 輸出:[5]
提示:
- 連結串列中節點數目為
n
1 <= n <= 500
-500 <= Node.val <= 500
1 <= left <= right <= n
進階: 你可以使用一趟掃描完成反轉嗎?
解題思路:
https://www.bilibili.com/video/BV1sd4y1x7KN(影片講解)
假設要反轉連結串列中的節點2,3,4
首先,反轉之後,從原連結串列(圖中第二條連結串列藍色和黑色部分)來看,反轉段的上一個節點為p0,反轉段的頭節點為pre,反轉段的後一個節點為cur
然後,處理反轉段的前面和後面節點(圖中粉色部分)
程式碼(C++/Python):
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution: def reverseBetween(self, head: Optional[ListNode], left: int, right: int) -> Optional[ListNode]: # 使用dummy防止left節點是連結串列頭結點,簡化程式碼邏輯 dummy=ListNode(next=head) p0=dummy #p0指向反轉連結串列段的前一個節點 for _ in range(left-1): p0=p0.next pre=None cur=p0.next # 反轉連結串列 for _ in range(right-left+1): nxt=cur.next cur.next=pre pre=cur cur=nxt # 處理反轉段的前後結點 p0.next.next=cur p0.next=pre return dummy.next
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* reverseBetween(ListNode* head, int left, int right) { ListNode dummy(0,head); ListNode* p0=&dummy; for(int i=0;i<left-1;i++){ p0=p0->next; } ListNode* cur=p0->next; ListNode* pre=nullptr; ListNode* nxt=nullptr; for(int i=0;i<right-left+1;i++){ nxt=cur->next; cur->next=pre; pre=cur; cur=nxt; } p0->next->next=cur; p0->next=pre; return dummy.next;
解題總結:
注意,反轉後的連結串列段,從原連結串列上看其前後節點的位置。