剑指24. 反转链表 && LeetCode 206. Reverse Linked List

题目

 

输入一个链表,反转链表后,输出新链表的表头。

Reverse a singly linked list.

Example:

Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL

Follow up:

A linked list can be reversed either iteratively or recursively. Could you implement both?


2022.12.19

给想复杂了……还用了dummyHead,然后发现dummyHead一会儿成环了一会儿多了个0……才意识到根本不需要dummyHead……以及时隔两年,还是不会写递归……

 2020.10.13 Java

差点没给写出来,吓得我以为我连反转链表都不会了。看了下自己新写的代码比以前的要简洁多了,有进步。对比了一下solutions居然除了变量名temp它起的是tempNext以外完全一毛一样,惊呆。

Runtime: 0 ms, faster than 100.00% of Java online submissions for Reverse Linked List.

Memory Usage: 38.7 MB, less than 6.72% of Java online submissions for Reverse Linked List.

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode curr = head;
        ListNode prev = null;
        while (curr != null) {
            ListNode temp = curr.next;
            curr.next = prev;
            prev = curr;
            curr = temp;
        }
        return prev;
    }
}

还是不会写递归,唉。知道了思路也在head.next.next=head那里卡住了。

Runtime: 0 ms, faster than 100.00% of Java online submissions for Reverse Linked List.

Memory Usage: 39.1 MB, less than 6.72% of Java online submissions for Reverse Linked List.

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode node = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return node;
    }
}

这道题没有什么特殊的技巧,就是普普通通地做就好了,也是一道非常经典的题,面试高频题。链表的题首先要考虑给出的头节点为空的情况,直接返回NULL。反转链表这个要格外注意不要把链表给断了,因此我们设置三个指针,分别指向当前节点curr、前一节点prev和后一节点next。在while循环中遍历整个链表,小心翼翼地将curr的next设为prev,并把prev和curr向后挪动一个,直到curr的next为空时达到了链表的尾部,把最后的curr设为反转链表的头节点:

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if (!pHead) {
            return NULL;
        }
        
        ListNode* prev = NULL;
        ListNode* curr = pHead;
        ListNode* new_head = NULL;
        
        while (curr) {
            ListNode* next = curr->next;
            
            if (!next) {
                new_head = curr;
            }
            
            curr->next = prev;
            prev = curr;
            curr = next;
        }
        
        return new_head;
    }
};

 另外一种递归方法,我理解了好久才搞明白,其实还是比较难想的。首先递归基是当参数中的pHead为空或者pHead->next为空时,就返回pHead,作为反转链表的头节点。接下来通过递归调用这个函数,把递归返回的结果(其实仔细看会发现每次返回的都是原链表的最后一个节点,也就是新链表的头)存起来,然后把当前指向的节点的下一个节点的next设为它自己(这就把指针反过来了),再把当前节点的next设为空,方便下一次设置next(毕竟当前节点在下一次就是前面那句提到的“当前节点的下一节点了),最后返回的就是之前存起来的新链表的头。画了个图:

代码如下:

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if (!pHead || !pHead->next) {
            return pHead;
        }
        
        ListNode* pReversedNode = ReverseList(pHead->next);
        
        pHead->next->next = pHead;
        pHead->next = NULL;
        
        return pReversedNode;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值