【刷题 issue15】程序员代码面试指南 —— IT 名企算法与数据结构题目最优解

第二章 链表问题

2.5 反转部分单向链表

【题目】

给定一个单向链表的头节点 head,以及两个整数 from 和 to,在单向链表上吧第 from 个节点到底 to 个节点这一部分进行反转。

【要求】

  1. 如果链表长度为 N,时间复杂度要求为 O(N),额外空间复杂度要求为 O(1)。
  2. 如果不满足 1≤from≤to≤N,则不需要调整。

【难度】

士 ★☆☆☆

【题解】

本题可能出现更换头节点的问题,整个处理过程如下:

  1. 先判断是否满足 1≤from≤to≤N,如果不满足,则无需调整。
  2. 找到第 from-1 个节点 fPre 和第 to+1 个节点 tPos。fPre 即反转部分的钱一个节点,tPos 即反转部分的的后一个节点。把反转的部分先反转,然后正确的连接 fPre 和 tPos。
  3. 如果 fPre 为空,说明反转部分是包含头节点的,则返回新的头节点,也就是没反转之前反转部分的最后一个节点,也是反转之后反转部分的第一个节点;如果 fPre 不为空,则返回就的头节点。

【实现】

  • ReversePartLinkedList.java
public class ReversePartLinkedList {

    private static class Node {
        public int value;
        public Node next;

        public Node(int value) {
            this.value = value;
        }
    }

    private Node head;

    public ReversePartLinkedList(int[] arr) {
        buildSingleLinkedList(arr);
    }

    private void buildSingleLinkedList(int[] arr) {
        if (arr != null && arr.length != 0) {
            Node preNode = this.head = new Node(arr[0]);
            for (int i = 1; i < arr.length; i++) {
                preNode = preNode.next = new Node(arr[i]);
            }
        }
    }

    public void reversePartLinkedList(int from, int to) {
        if (from >= to || from < 1) {
            return;
        }
        if (this.head == null || this.head.next == null) {
            return;
        }
        int len = 1;
        Node curNode = this.head;
        Node fPreNode = null;
        Node tPosNode = null;
        while (curNode != null) {
            ++len;
            fPreNode = (len == from - 1) ? curNode : fPreNode;
            tPosNode = (len == to + 1) ? curNode : tPosNode;
            curNode = curNode.next;
        }
        if (to > len) {
            return;
        }
        curNode = (fPreNode == null) ? this.head : fPreNode.next;
        Node postNode = curNode.next;
        curNode.next = tPosNode;
        Node nextNode = null;
        while (nextNode != tPosNode) {
            nextNode = postNode.next;
            postNode.next = curNode;
            curNode = postNode;
            postNode = nextNode;
        }
        if (fPreNode != null) {
            fPreNode.next = curNode;
        }
    }

}
  • Test.java
public class Test {

    private ReversePartLinkedList partLinkedList;

    public Test(int[] arr) {
        this.partLinkedList = new ReversePartLinkedList(arr);
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        Test test = new Test(arr);
        test.partLinkedList.reversePartLinkedList(2, 4);
    }

}
发布了147 篇原创文章 · 获赞 72 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Pranuts_/article/details/100171557