算法:反转单向链表

  • 将一个单向链表反转,最终输出反转后的链表的头节点
废话少说,直接上代码:

单向链表模型,如下

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

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        ListNode node = this;
        while (node !=null){
            sb.append(node.val);
            node = node.next;
            if (null != node) sb.append(",");
        }
        sb.append("]");
        return sb.toString();
    }
}
方法一:遍历元素,依此反转位置
    private static ListNode reverseNode1(ListNode root){
        ListNode currNode = root.next;//将第二个node作为遍历开始的元素
        ListNode reverseNode = root;//将第一个node作为反转的开头
        root.next = null;
        while (currNode != null){
            ListNode temp = currNode.next;//后面没有反转的node放在temp保存
            //将之前反转的node放在当前node后面,构建新的反转序列,这是反转的关键操作
            currNode.next = reverseNode;
            reverseNode = currNode ;//这是反转后node的更新
            currNode = temp;//将后面未反转的node保存到temp
        }
        return reverseNode;
    }
方法二:新建链表,依此将原有元素插入到头部
    private static ListNode reverseNode2(ListNode node) {
        ListNode curNode = node.next;//将第二个元素作为遍历元素的开始
        ListNode reverseNode = new ListNode(node.val);//将第一个元素作为反转序列的开头,注意是仅仅copy单个元素
        while (curNode != null){
            int val = curNode.val;
            ListNode curUnit = new ListNode(val);//将当前的元素做单个copy
            curUnit.next = reverseNode;//将之前反转好的序列放在当前元素的后面,反转的关键步骤
            reverseNode = curUnit;//更新反转后的序列
            curNode = curNode.next;//更新当前元素为下一个
        }

        return reverseNode;
  }
测试
    public static void main(String[] arg0){
        ListNode node1 = new ListNode(1);
        ListNode node2 = new ListNode(2);
        ListNode node3 = new ListNode(3);
        ListNode node4 = new ListNode(4);
        ListNode node5 = new ListNode(5);
        node1.next  = node2;
        node2.next  = node3;
        node3.next  = node4;
        node4.next  = node5;
        
        //以下测试二选其一,否则互相影响
        System.out.println("result 1 = "+reverseNode1(node1).toString());
        //System.out.println("result 2 = "+reverseNode2(node1).toString());
    }

结果:两个运行结果一致,均为反转后的序列

result 1 = [5,4,3,2,1]
总结
  1. 方法一与方法二的时间复杂度均为n-1 (假设链表长度为n)
  2. 方法一的空间复杂度为1,那么方法二的空间复杂度就是2;double了,因为方法二将整个链表完整的复制了一遍
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值