剑指offer 24 反转链表

@author: sdubrz
@date: 7/25/2020 10:46:14 AM     
难度: 简单
考察内容: 链表
@e-mail: lwyz521604#163.com
题目来自《剑指offer》 电子工业出版社

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

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

限制:

0 <= 节点个数 <= 5000

解法一 栈

对于颠倒顺序的问题,最容易想到的解法就是用栈来实现:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head==null) {
			return null;
		}
		if(head.next==null) {
			return head;
		}
		
		// 剩下的情况就是链表中至少有两个节点的情况
		Stack<ListNode> stack = new Stack<>();
		ListNode current = head;
		while(current!=null) {
			stack.push(current);
			current = current.next;
		}
		
		ListNode list2 = stack.pop();
		ListNode current2 = list2;
		while(stack.size()>1) {
			current2.next = stack.pop();
			current2 = current2.next;
		}
		ListNode lastNode = stack.pop();
		lastNode.next = null;
		current2.next = lastNode;
		
		return list2;
    }
}

但是对于链表的反转问题,栈的解法效率并不高。

执行结果:通过 显示详情
执行用时:1 ms, 在所有 Java 提交中击败了6.67%的用户
内存消耗:39.5 MB, 在所有 Java 提交中击败了100.00%的用户

解法二 一次遍历链表

遍历一次链表,并在遍历的过程中改变next的指向关系,具体实现如下:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head==null) {
			return null;
		}
		if(head.next==null) {
			return head;
		}
		
		// 剩下的情况就是链表中至少有两个节点的情况
		ListNode pre = head;  // 前一个节点
		ListNode current = pre.next;  // 当前节点
		pre.next = null;
		while(current.next!=null) {
			ListNode back = current.next;
			current.next = pre;
			pre = current;
			current = back;
		}
		current.next = pre;
		
		return current;
    }
}

这种方法的效率要明显高于栈实现的版本:

执行结果:通过 显示详情
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:40 MB, 在所有 Java 提交中击败了100.00%的用户
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值