剑指Offer 24. 反转链表

剑指Offer 24. 反转链表

  • 题目描述
  • 题解
    • 头插法
    • 三指针法
  • 运行结果

题目描述

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

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

题解

头插法

定义新建链表函数与头插函数,当输入不为空时新建链表,为空直接返回空,然后通过头插法插入剩余结点,新建链表即为所求,空间复杂度为O(n),时间复杂度也为O(n)。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 
struct ListNode* creatList(int x) {
     
    struct ListNode* head;
    head = (struct ListNode*)malloc(sizeof(struct ListNode));
    if (head) {
     
        head->val = x;
        head->next = NULL;
    }
    return head;
}

struct ListNode* insertListHead(struct ListNode* curr, int x) {
     
    struct ListNode* prev;
    prev = (struct ListNode*)malloc(sizeof(struct ListNode));
    prev->val = x;
    prev->next = curr;
    curr = prev;
    return curr;
}

struct ListNode* reverseList(struct ListNode* head) {
     
    struct ListNode* ans = NULL;
    if (head != NULL) {
     
        ans = creatList(head->val);
        head = head->next;
    }
    while (head != NULL) {
     
        ans = insertListHead(ans ,head->val);
        head = head->next;
    }
    return ans;
}

三指针法

此方法为单链表逆转标准方法,定义三个指针分别指向先前、当前、下一结点,当当前结点不为空时执行以下操作:

初始curr指向头结点
1.next 指向 curr指向的结点的下一结点
2.curr指向的结点内部的next 指向 prev指向的位置 (若prev为空,二者全指向空)
3.prev 指向 curr指向的结点
4.curr 指向 next指向的结点

听起来比较拗口,通过画图可以很好理解,该算法时间复杂度无提升,为单次遍历O(n),但是空间复杂度为常数级O(1)。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 
struct ListNode* reverseList(struct ListNode* head) {
     
    struct ListNode* prev = NULL;//指向先前结点
    struct ListNode* curr = head;//指向当前结点
    struct ListNode* next = NULL;//指向下一结点
    while (curr) {
     
        next = curr->next;
        curr->next = prev;
        prev = curr;
        curr = next;
    }
    return prev;
}

运行结果

剑指Offer 24. 反转链表_第1张图片

你可能感兴趣的:(LeetCode刷题总结,链表,算法,指针,数据结构,单链表)