力扣链表刷题笔记-206反转链表

206. 反转链表

题目描述:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]

提示:

链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000

解法一:数组

思路:遍历链表将链表节点存储在数组中,从后向前遍历数组依次将节点翻转
代码如下:

struct ListNode* reverseList(struct ListNode* head){
    struct ListNode* arr[5001];
    struct ListNode* p=head;
    int i;
    if(head==NULL){
        return head;
    }
    for( i=0;p;i++){
        arr[i]=p;
        p=p->next;
    }
    int end=i-1;
    for(i-=1;i>0;i--){
        arr[i]->next=arr[i-1];
    }
    arr[0]->next=NULL;
    return arr[end];
}

解法二:双指针

在这里要引入虚拟头节点的概念,在链表中对头节点的处理往往需要特殊对待,因此我们可以设置一个虚拟头节点,并让他指向实际头节点。这一步操作让头节点去特殊化,可以与普通节点共同处理。

  • 首先定义三个指针pre,cur,next
  • pre初始化为虚拟头节点
  • cur初始化为实际头节点
  • next负责记录cur后的节点(防止翻转后访问不到该节点)
  • pre,cur,next为一个最小单位循环
  • 第一步: 令cur->next=pre实现局部翻转
  • pre,cur,next向后推一个节点
struct ListNode *reverseList(struct ListNode *head)
{
  if (head == NULL || head->next == NULL)
  {
    return head;
  }
  struct ListNode *pre = NULL;
  struct ListNode *cur = head;
  struct ListNode *next = head->next;
  while (next)
  {
    cur->next = pre;
    pre = cur;
    cur = next;
    next = next->next;
  }
  cur->next = pre;
  return cur;
}

解法三:递归

递归三要素:

  • 递归终止条件:若参数节点不为NULL则将当前参数节点的后继节点传入递归函数中,一直到链表末尾
  • 重复执行结构:将参数节点head后的节点翻转,即head->next->next=head
  • 返回值:返回翻转后的链表头即原链表尾
struct ListNode *reverseList(struct ListNode *head) {
  if (head == NULL ||head->next == NULL ) {
    return head;
  }
  struct ListNode *ret = reverseList(head->next);
  head->next->next = head;
  head->next = NULL;
  return ret;
}

解法四:双指针妙用

思想:将pre指针的后继指向cur的后一个节点从而实现记录该节点的功能

struct ListNode *reverseList(struct ListNode *head) {
  if (head == NULL || head->next == NULL) {
    return head;
  }
  struct ListNode *pre = head;
  struct ListNode *cur = head->next;
  struct ListNode *next = cur->next;
  while (next) {
    cur->next = pre;
    head->next = next;
    pre = cur;
    cur = next;
    next = next->next;
  }
    head->next=NULL;
    cur->next = pre;
  return cur;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值