反转部分单向链表
给定一个单向链表的头节点head,以及反转的起始点from和终止点to ,将起始点和终止点中间的部分进行反转
例如 1->2->3->4->5->6, from为2, to为4,反转后的结果为 1->4->3->2->5->6。如果不满足 1 <= from <= to <= N,则不用调整
【解析】
解题思路:
1、首先判断1 <= from <= to <= N是否满足,如果不满足,则不用调整
2、然后找到需要反转的第一个节点的上一个节点 fPre,然后找到需要反转的的节点的最后一个节点的下一个节点 tPos,将需要反转的进行反转,将这两个正确连接
3、可能存在换头的情况,如果fPre 为null,说明需要反转的部分包括头节点,这时需要换头,如果不等于null,则直接返回head,但是要注意连接
package com.test; import com.test.ListNode; /** * Created by Demrystv. */ public class ReversePartOfListNode { public ListNode reversePart(ListNode head, int from, int to){ int len = 0; ListNode node1 = head; ListNode fPre = null; ListNode tPos = null; while (node1 != null){ len++; //找到需要反转的第一个节点的上一个节点 fPre,然后找到需要反转的的节点的最后一个节点的下一个节点 tPos fPre = len == from - 1 ? node1 : fPre; tPos = len == to + 1 ? node1 : tPos; node1 = node1.next; } if (from > to || from < 1 || to > len){ return head; } // 让node1 位于需要反转的第一个节点,node2 位于node1的下一个节点 node1 = fPre == null ? head : fPre.next; ListNode node2 = node1.next; // 对于初始化条件应该首先建立好 连接 // 注意是单向链表,主需要维护好next 即可,即只想后看,没必要看前面 // 如果对于双向链表,逻辑一样,但是需要同时维护向前看 和 向后看 node1.next = tPos; ListNode next = null; while (node2 != tPos){ next = node2.next; node2.next = node1; node1 = node2; node2 = next; } // 判断fPre 是否包含头节点,针对有可能出现换头的情况 if (fPre != null){ fPre.next = node1; return head; } return node1; } }