【leetcode】反转链表

                                                       反转链表

一、要求

反转一个单链表。

示例:

输入: 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));
    }

}

测试输出为:

全部评论

相关推荐

点赞 收藏 评论
分享
正在热议
# 牛客帮帮团来啦!有问必答 #
1147155次浏览 17113人参与
# 通信和硬件还有转码的必要吗 #
11074次浏览 101人参与
# OPPO开奖 #
18822次浏览 264人参与
# 和牛牛一起刷题打卡 #
18514次浏览 1619人参与
# 实习与准备秋招该如何平衡 #
202949次浏览 3619人参与
# 大厂无回复,继续等待还是奔赴小厂 #
4753次浏览 29人参与
# 不去互联网可以去金融科技 #
19346次浏览 247人参与
# 通信硬件薪资爆料 #
265410次浏览 2482人参与
# 国企是理工四大天坑的最好选择吗 #
2158次浏览 34人参与
# 互联网公司评价 #
97476次浏览 1277人参与
# 简历无回复,你会继续海投还是优化再投? #
24996次浏览 354人参与
# 0offer是寒冬太冷还是我太菜 #
454424次浏览 5121人参与
# 国企和大厂硬件兄弟怎么选? #
53796次浏览 1010人参与
# 参加过提前批的机械人,你们还参加秋招么 #
14615次浏览 349人参与
# 硬件人的简历怎么写 #
82251次浏览 852人参与
# 面试被问第一学历差时该怎么回答 #
19360次浏览 212人参与
# 你见过最离谱的招聘要求是什么? #
27462次浏览 246人参与
# 学历对求职的影响 #
161059次浏览 1804人参与
# 你收到了团子的OC了吗 #
538168次浏览 6382人参与
# 你已经投递多少份简历了 #
343784次浏览 4960人参与
# 实习生应该准时下班吗 #
96829次浏览 722人参与
# 听劝,我这个简历该怎么改? #
63469次浏览 620人参与
牛客网
牛客企业服务