剑指offer--24.反转链表

题目描述:

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

示例:

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

限制:

0 <= 节点个数 <= 5000

思路:双指针迭代,递归法

注意双指针迭代除了cur和pre两个指针之外,还需要一个辅助的指针temp用来保存cur.next节点的值

解决方法:

1. 递归解法
递归的两个条件:
(1)终止条件:当前节点或下一个节点等于null
(2)在函数内部,改变节点的指向:head.next.next=head

找到当前链表的尾结点,就是反转链表的头结点
分两种情况:当链表只有空节点、到达链表的尾节点

head.next.next=head;这样理解:

如果链表是 1 -> 2 -> 3 -> 4 -> 5,那么此时的cur就是5

而head是4,head的下一个是5,下下一个是空

所以head.next.next 就是4 -> 5

cur是不变的,始终都指向尾节点

/**
 * 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 || head.next == null)
            return head;
        ListNode cur = reverseList(head.next);  //递归
        head.next.next = head; //完成节点的反转
        head.next = null; //防止链表成环
        return cur;     
    }
}

双指针迭代更好理解

2. 双指针迭代
先申请两个指针:cur pre;
还需要一个辅助的指针temp用来保存cur.next节点的值
pre最初指向null;
cur指向头节点head,然后不断遍历cur,每次遍历到cur时,都将cur的next指向pre;
然后pre和cur都前进一位;
都迭代完时(cur变成null),pre就是最后一个节点了
(temp节点相当于中间变量)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode cur = head;
        ListNode pre = null;
        ListNode temp = null;
        while(cur != null){
            temp = cur.next; //保存当前节点的下一个节点
            cur.next = pre; //当前节点cur的next指向pre
            //cur pre节点同时向前移动一个节点
            pre = cur;
            cur = temp;
        } 
        return pre;   
    }
}

如果不用辅助指针temp,代码会这样写这样是错的

while(cur != null){
            cur.next = pre; 
            pre = cur;
            cur = cur.next;
        } 
 //代码只会跑一次,之后cur=null ,pre=1

完整代码这样写:不知道为啥运行不出来?

package cn.sxt.arrays;
/**
 * 反转链表
 * @author Star Ma
 *
 */
public class ListNodeTest {
	public static class ListNode{
		int val;
		ListNode next;
		
		ListNode(int x){
			val = x;
		}
		
		public String show() {
			return this.val + "->" + (this.next==null ? "null" : this.next.show());
		}
	}
	//递归
	public ListNode reverseList(ListNode head){
		if(head == null || head.next == null) {
			return head;
		}
		ListNode cur = reverseList(head.next);
		head.next.next = head;
		head.next = null;
		return cur;
	}
	public void testReverse(){
		ListNode a = new ListNode(1);
		ListNode b = new ListNode(2);
		ListNode c = new ListNode(3);
		a.next = b;
		b.next = c;
		
		System.out.println(a.show());
	}
	
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值