【leetcode】反转链表

版权声明:转载请注明 https://blog.csdn.net/qq_33591903/article/details/82954083

                                                       反转链表

一、要求

反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?

链表结点定义为:

 public class ListNode {
        int val;
        ListNode next;

        ListNode(int val) {
            this.val = val;
        }
    }

二、解法

这里我们采用两种方法,分别是迭代与递归。

(1)迭代

从链表头部开始处理,我们需要定义三个连续的结点pPre,当前需要反转的结点pCur,下一个需要反转的结点pFuture和一个永远指向头结点的pFirst。每次我们只需要将pPre指向pFuture,pCur指向pFirst,调整头结点pFirst,调整当前需要反转的结点为下一个结点即pFuture,最后调整pFuture为pCur的next结点。

代码演示

public ListNode reverseList(ListNode head) {
        if (head == null) {
            return null;
        }
        //始终指向链表的头结点
        ListNode pFirst = head;
        //三个结点中的第一个结点
        ListNode pPre = pFirst;
        //当前需要反转的结点
        ListNode pCur = head.next;
        //下一次即将需要反转的结点
        ListNode pFuture = null;
        while (pCur != null) {
            pFuture = pCur.next;
            pPre.next = pFuture;
            pCur.next = pFirst;
            pFirst = pCur;
            pCur = pFuture;
        }
        return pFirst;
    }

反转过程如下

代码提交结果:


(2)递归

递归与迭代不同,递归是从链表的尾结点开始,反转尾结点与前一个结点的指向。

代码演示:

public ListNode reverseList2(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode pNext = head.next;
        head.next = null;
        ListNode reverseListNode = reverseList2(pNext);
        pNext.next = head;
        return reverseListNode;
    }

反转的过程为:

代码提交结果:


三、整个测试代码

package leetcode.day1006;


/**
 * Created by 戚春阳 2018/10/6
 * 反转单链表
 */
public class ReverseListNode {
    public static class ListNode {
        int val;
        ListNode next;

        ListNode(int val) {
            this.val = val;
        }
    }

    /**
     * 迭代方式
     *
     * @param head 翻转前链表的头结点
     * @return 翻转后链表的头结点
     */
    public ListNode reverseList(ListNode head) {
        if (head == null) {
            return null;
        }
        //始终指向链表的头结点
        ListNode pFirst = head;
        //三个结点中的第一个结点
        ListNode pPre = pFirst;
        //当前需要反转的结点
        ListNode pCur = head.next;
        //下一次即将需要反转的结点
        ListNode pFuture = null;
        while (pCur != null) {
            pFuture = pCur.next;
            pPre.next = pFuture;
            pCur.next = pFirst;
            pFirst = pCur;
            pCur = pFuture;
            System.out.println("迭代的反转过程:" + getList(pFirst));
        }
        return pFirst;
    }

    /**
     * 递归方式
     *
     * @param head 翻转前链表的头结点
     * @return 翻转后链表的头结点
     */
    public ListNode reverseList2(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode pNext = head.next;
        head.next = null;
        ListNode reverseListNode = reverseList2(pNext);
        pNext.next = head;
        System.out.println("递归的反转过程:" + getList(reverseListNode));
        return reverseListNode;
    }

    /**
     * 将数组转化为链表
     *
     * @return 链表的头结点
     */
    public ListNode setList() {
        int a[] = {1, 2, 3, 4, 5};
        ListNode pHead = new ListNode(a[0]);
        ListNode pNext = pHead;
        for (int i = 1; i < a.length; i++) {
            ListNode pTemp = new ListNode(a[i]);
            pNext.next = pTemp;
            pNext = pTemp;

        }
        return pHead;
    }

    /**
     * @param pHead 链表头结点
     * @return 链表的字符串表达形式
     */
    public String getList(ListNode pHead) {
        int a[] = new int[5];
        ListNode pCur = pHead;
        int point = 0;
        while (pCur != null) {
            a[point] = pCur.val;
            pCur = pCur.next;
            point++;
        }
        StringBuffer sb = new StringBuffer();
        sb.append("[");
        for (int temp : a) {
            sb.append(temp + " ");
        }
        sb.append("]");
        return sb.toString();

    }

    public static void main(String args[]) {
        ReverseListNode test = new ReverseListNode();

        System.out.println("原始链表为:");
        ListNode node = test.setList();
        System.out.println(test.getList(node));

        System.out.println("-------------------------");

        ListNode nodeReverse = test.reverseList(node);
        System.out.println("迭代的最终结果:" + test.getList(nodeReverse));

        System.out.println("-------------------------");

        //可以将之前反转的链表再反转回来
        ListNode nodeReverse2 = test.reverseList2(nodeReverse);
        System.out.println("递归的最终结果:" + test.getList(nodeReverse2));
    }

}

测试输出为:

猜你喜欢

转载自blog.csdn.net/qq_33591903/article/details/82954083