题目
原题:https://leetcode-cn.com/problems/reverse-linked-list-ii/
题解
反正某一部分的节点,当反正的节点如果从头结点开始,会存在复杂的判断,所以一般会构造一个虚拟节点,来避免这种问题的讨论。
另外还要注意的是,链表的更改下一节点数据时,要考虑用临时节点来做,以免丢失节点数据。
LeetCode 上的这道题,一开始连解题思路都没有,看答案有些步骤有种根本想不到的感觉,感觉他们是有上帝视角,不然有些步骤都想不到可以这么做,在多抄了几遍答案后,思考这个问题的本质其实就是两个变量交换值,a=1,b=2,那么需要变量 c 来暂存下,不然不能完成交换,只不过这两个变量挂在了链表上。同理,要把链表 a:
5-4-3-2-1
反正部分节点,得到链表 b:
5-2-3-4-1
那么我们需要链表 c 来暂存下,因此这道题,首先我们要开辟两个新的内存空间,但是这也的好处就是只要遍历链表一次就行。
public ListNode reverseBetween(ListNode head, int left, int right) {// 设置 dummyNode 是这一类问题的一般做法ListNode dummyNode = new ListNode(-1);dummyNode.next = head;ListNode pre = dummyNode;// 找到要反转的头结点for (int i = 0; i < left - 1; i++) {pre = pre.next;}// 用临时节点操作,防止节点丢失,cur是要反转的头结点ListNode cur = pre.next;ListNode next;// right - left 表示要反转的节点个数// 这里链表中的节点交换位置,可以理解为两个变量交换位置,那么// 需要一个临时变量来暂存要交换的数据for (int i = 0; i < right - left; i++) {// 开始反转操作,pre 原始数据,cur和next都是用来暂存临时节点,// cur当前节点数据,next下一个要反转的节点数据// 每次调换一个节点,例如: 5-4-3-2-1 => 5-3-4-2-1 => 5-2-3-4-1// 不好理解需要画个图next = cur.next;cur.next = next.next;// 将已经反转的节点赋值到新的节点next.next = pre.next;pre.next = next;}return dummyNode.next;}
总结
如果不知道怎么做,可以多看别人的解题思路,多抄几遍代码,我就是这样,一开理解不了,拆了好多遍后,能模仿,然后在思考下,为什么这么做。总之,不会的情况,多模仿。
