翻转链表

题目
定义一个函数,输入一个链表的头结点,反转该链表并输出反转后的链表。
解题思路
1 暴力法
借助外部空间实现。这里可以将单链表节点储存到链表中,然后按照链表的索引逆序进行反转。

package Arithmetic;

import java.util.ArrayList;
import java.util.List;

public class ReverseListNode {
    class ListNode {
        private int val;//节点值
        private ListNode next;//下一个节点

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

        //从头到尾打印链表节点
        @Override
        public String toString() {
            String result = "";//保存结果
            ListNode head = this;//当前结点
            while (head != null) {
                result += head.val;
                if (head.next != null)
                    result += "-->";
                head = head.next;
            }
            return result;
        }
    }

    //暴力法
    public static ListNode ReverseListNode(ListNode head) {
        if (head == null)
            return null;
        List<ListNode> listNodes = new ArrayList<>();//用来保存链表节点
        while (head != null) {
            listNodes.add(head);//保存节点
            head = head.next;
        }

        for (int i = listNodes.size() - 1; i >= 0; i--) {//从后往前遍历
            ListNode listNode = listNodes.get(i);
            if (i == 0) {
                listNode.next = null;
            } else {
                listNode.next = listNodes.get(i - 1);
            }
        }
        head = listNodes.get(listNodes.size() - 1);//现在的头结点为链表的尾结点
        return head;
    }

    public static void main(String[] args) {
        ReverseListNode reverseListNode = new ReverseListNode();
        ListNode listNode1 = reverseListNode.new ListNode(1);
        ListNode listNode2 = reverseListNode.new ListNode(2);
        ListNode listNode3 = reverseListNode.new ListNode(3);
        listNode1.next = listNode2;
        listNode2.next = listNode3;
        System.out.print("链表反转前:");
        System.out.println(listNode1);
        System.out.print("链表反转后:");
        System.out.println(ReverseListNode(listNode1));
    }
}

2 递归
原地反转,不借助外部空间,在O(n)的时间复杂度内完成。

package Arithmetic;

public class ReverseListNode {
    class ListNode {
        private int val;//节点值
        private ListNode next;//下一个节点

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

        //从头到尾打印链表节点
        @Override
        public String toString() {
            String result = "";//保存结果
            ListNode head = this;//当前结点
            while (head != null) {
                result += head.val;
                if (head.next != null)
                    result += "-->";
                head = head.next;
            }
            return result;
        }
    }

    //递归
    public static ListNode ReverseListNode(ListNode head) {
        if (head == null || head.next == null)
            return head;
        ListNode next = head.next;//保存头节点的next
        head.next = null;//将头节点与链表断开
        ListNode neWHead = ReverseListNode(next);//递归
        next.next = head;//后一个节点指向前一个结点
        return neWHead;
    }

    public static void main(String[] args) {
        ReverseListNode reverseListNode = new ReverseListNode();
        ListNode listNode1 = reverseListNode.new ListNode(1);
        ListNode listNode2 = reverseListNode.new ListNode(2);
        ListNode listNode3 = reverseListNode.new ListNode(3);
        listNode1.next = listNode2;
        listNode2.next = listNode3;
        System.out.print("链表反转前:");
        System.out.println(listNode1);
        System.out.print("链表反转后:");
        System.out.println(ReverseListNode(listNode1));
    }
}

3.迭代
创建辅助节点,从前往后依次取链表节点插入到辅助节点的后面(头插法)

package Arithmetic;

public class ReverseListNode {
    class ListNode {
        private int val;//节点值
        private ListNode next;//下一个节点

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

        //从头到尾打印链表节点
        @Override
        public String toString() {
            String result = "";//保存结果
            ListNode head = this;//当前结点
            while (head != null) {
                result += head.val;
                if (head.next != null)
                    result += "-->";
                head = head.next;
            }
            return result;
        }
    }

    //迭代-头插法
    public static ListNode ReverseListNode(ListNode head) {
        ListNode newList = new ReverseListNode().new ListNode(-1);//辅助结点
        while (head != null){
            ListNode next = head.next;//取头节点作为待插入结点
            head.next = newList.next;//头节点指向辅助结点的next
            newList.next = head;//辅助结点指向头节点
            head = next;//将头节点后移
        }
        return newList.next;
    }

    public static void main(String[] args) {
        ReverseListNode reverseListNode = new ReverseListNode();
        ListNode listNode1 = reverseListNode.new ListNode(1);
        ListNode listNode2 = reverseListNode.new ListNode(2);
        ListNode listNode3 = reverseListNode.new ListNode(3);
        listNode1.next = listNode2;
        listNode2.next = listNode3;
        System.out.print("链表反转前:");
        System.out.println(listNode1);
        System.out.print("链表反转后:");
        System.out.println(ReverseListNode(listNode1));
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值