题目:
给你单链表的头指针 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
进阶: 你可以使用一趟扫描完成反转吗?
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/reverse-linked-list-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
一、头插法
1.首先定义一个虚拟头结点指向原始头结点,可以减少对头结点的特殊处理,将头结点当做普通结点处理;
2.定义两个指针一个为pre,一个为cur;
3.确定pre和cur指针的位置,需要根据题中给定的left值进行确定,将pre移动到第一个需要反转的结点的前面,将cur移动到需要反转的第一个结点上;
4.将cur后面一个结点temp保存,将当前cur指向cur的下下个结点,即cur.next=cur.next.next , 然后将保存的结点插入到pre后面;
5.重复步骤4;
6.最后返回dummyHead.next。
解释:
temp.next = pre.next这里为什么不能写成temp.next = cur?
看上面的图解就可以看出,cur所指向的结点没有变过,但是所在的位置是一直在变化的,pre和cur中间会一直插入结点,而每次插入都是在pre的后面。如果写成temp.next = cur就会删除上面已经反转的结点,比如4和3。
java代码:
1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode() {} 7 * ListNode(int val) { this.val = val; } 8 * ListNode(int val, ListNode next) { this.val = val; this.next = next; } 9 * } 10 */ 11 class Solution { 12 public ListNode reverseBetween(ListNode head, int left, int right) { 13 ListNode dummyHead = new ListNode(0,head); 14 //定义两个指针pre和cur 15 ListNode pre = dummyHead; 16 ListNode cur = dummyHead.next; 17 18 //先确定两个指针的初始位置,pre应该在left-1,cur=left 19 for(int i = 1; i < left; i++){ 20 pre = pre.next; 21 cur = cur.next; 22 } 23 //插入 24 for(int j = 1; j < right - left + 1; j++){ 25 //保存cur的下一个结点 26 ListNode temp = cur.next; 27 //使cur指向它的下下个结点 28 cur.next = cur.next.next; 29 //将保存的结点插入 30 temp.next = pre.next; 31 pre.next = temp; 32 } 33 return dummyHead.next; 34 35 } 36 }
python3代码:
1 # Definition for singly-linked list. 2 # class ListNode: 3 # def __init__(self, val=0, next=None): 4 # self.val = val 5 # self.next = next 6 class Solution: 7 def reverseBetween(self, head: Optional[ListNode], left: int, right: int) -> Optional[ListNode]: 8 dummyHead = ListNode(0,head) 9 pre,cur = dummyHead,dummyHead.next 10 11 # 确定pre和cur的位置 12 for i in range(1,left): 13 cur = cur.next 14 pre = pre.next 15 16 # 插入操作 17 for i in range(1,right-left+1): 18 temp = cur.next 19 # 如果temp是尾结点cur.next为none 20 cur.next = temp.next if temp else None 21 22 temp.next = pre.next 23 pre.next = temp 24 25 return dummyHead.next
二、递归
reverseBetween():含义就是将拿到的链表进行反转,然后返回反转后的链表的头结点(不细想过程,很容易绕进去) 还没完全弄明白,待更~ 标签:pre,结点,java,cur,temp,python,next,链表,ListNode From: https://www.cnblogs.com/liu-myu/p/16707419.html