链表问题----反转部分单向链表

反转部分单向链表

  

  给定一个单向链表的头节点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;
    }
}

 

posted @ 2018-07-16 22:52  Demrystv  阅读(173)  评论(0编辑  收藏  举报