首页 > 剑指offer:面试题24. 反转链表

剑指offer:面试题24. 反转链表

题目:反转链表

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

示例:

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

限制:

0 <= 节点个数 <= 5000

解题:

方法一:双指针

  • 我们可以申请两个指针,第一个指针叫 new_next,最初是指向 old_next 的;
  • 第二个指针 old_next 指向 head,然后不断遍历 old_next;
  • 每次迭代到 old_next,都将 old_next 的 next 指向 new_next,然后 new_next 和 old_next 前进一位;
  • 都迭代完了(old_next 变成 null 了),new_next 就是最后一个节点了。
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/class Solution {
public:ListNode* reverseList(ListNode* head) {if (!head || !head->next) return head;ListNode* new_next = NULL,*old_next = head;while(old_next) {ListNode* tmp = old_next->next;old_next->next = new_next;new_next = old_next;old_next = tmp;}return new_next;}
};

方法二:递归

递归的两个条件:

  • 终止条件是当前节点或者下一个节点==null
  • 在函数内部,改变节点的指向,也就是 head 的下一个节点指向 head 递归函数那句

        head.next.next = head

class Solution {
public:ListNode* reverseList(ListNode* head) {if (!head || !head->next) return head;//递归终止条件是当前为空,或者下一个节点为空ListNode* cur = reverseList(head->next);//这里的cur就是最后一个节点//如果链表是 1->2->3->4->5,那么此时的cur就是5//而head是4,head的下一个是5,下下一个是空//所以head.next.next 就是5->4head->next->next = head;  head->next = NULL;  return cur;}
};

 

更多相关:

  • 题目:合并两个排序的链表 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。 示例1: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 限制: 0 <= 链表长度 <= 1000 解题: /*** Definition for singly-linked li...

  • LRU算法(Least Recently Used) 算是我们经常遇到的一种淘汰算法,其中内存管理模块进行内存页回收时有用到,针对不经常使用的内存页,LRU淘汰策略能够将该内存页回收给操作系统。 属于 我们操作系统设计中的 时间局部性原理,最长时间未被访问的数据优先淘汰,当内存中已存在的数据再次被访问时,则进行热度的提升。 本文为...

  • 题目描述 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 示例: 给定 1->2->3->4, 你应该返回 2->1->4->3. 方法一(递归): 将配对交换过程拆解为多个以两个元素为一对的子问题 …n(k-1) -> n(k)->n(k+1)...

  • 已知两个已排序链表头节点指针headA与headB,将这两个链表合并,合并后仍为 有序的,返回合并后的头节点。 主要步骤如下: 创建一个临时的头节点,头节点每次指向headA 或者 headB较小的节点当headA->data 比headB->data小的时候,headA的当前节点加入临时头节点,同时headA指针向后移动;否则h...

  • 题目:复杂链表的复制 请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。 示例 1: 输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]] 输出...

  • 给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。 你应当保留两个分区中每个节点的初始相对位置。 示例: 输入: head = 1->4->3->2->5->2, x = 3 输出: 1->2->2->4->3->5 使用双指针的方式,各自构造一个大元素的头节点和小元素...

  • 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。 说明:不允许修改给定的链表。 示例 1: 输入:head = [3,2,0,-4], pos = 1...

  • 题目描述如下: 反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。 说明: 1 ≤ m ≤ n ≤ 链表长度。 示例: 输入: 1->2->3->4->5->NULL, m = 2, n = 4 输出: 1->4->3->2->5->NULL 很明显这个题目是206 反转链表的进阶版 需要记录第m-1个节点和第n+1个...

  • 描述如下: 反转一个单链表。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 方法一:原地反转 数据结构如下 struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {}...