leetcode刷题-链表#2

本文详细解析了链表的基本操作,包括链表的反转、指定区间内的反转以及链表的重组,提供了迭代和递归两种实现方式,并附带代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

206. Reverse Linked List [easy]

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?

  • 思路1:用多个指针就好。ptr指向当前节点。pre上一个,next下一个。ptr->next指向pre。然后三个指针往后移一步就好。
  • 复杂度:time O(N), space O(1)
/**
 * 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 == NULL || head->next == NULL)
            return head;
        ListNode* pre = NULL, *ptr = head, *next;
        while(ptr) {
            next = ptr->next;
            ptr->next = pre;
            pre = ptr;
            ptr = next;
        }
        return pre;
    }
};
  • 思路2:怎么递归来处理?逆转一个链表a[:n],a[k+1:]都已经逆转了。这个时候a[k+2]和a[k]都指向a[k+1]。所以只要a[k+1]指向a[k]。a[k]指向NULL就可以。
  • 注意:a[k]一定要指向NULL。返回首节点的地方也有点tricky。
  • 复杂度:time O(N), space O(N)
/**
 * 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 == NULL || head->next == NULL)
            return head; //  return最后一个节点,也就是逆转后链表的首节点
        ListNode* p = reverseList(head->next);
        head->next->next = head;
        head->next = NULL;
        return p;
    }
};

92. Reverse Linked List II [medium]

Reverse a linked list from position m to n. Do it in one-pass.

Note: 1 ≤ m ≤ n ≤ length of list.

Example:

Input: 1->2->3->4->5->NULL, m = 2, n = 4
Output: 1->4->3->2->5->NULL
  • 思路:首先找到要反转部分的第一个和最后一个节点。要记住第一个节点的前一个节点。把最后一个节点的next设为NULL。然后把中间这部分用上面的方法逆转。之后在连接就可以。
  • 注意:
    • 逆转部分抽出一个方法,这样变量名不会混乱。可以复用上一问的内容。
    • 逆转结束后重新连接要注意一下。
    • 复杂度:时间O(n)。空间O(1)
/**
 * 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 == NULL || head->next == NULL)
            return head;
        ListNode* pre = NULL, *ptr = head, *next;
        while(ptr) {
            next = ptr->next;
            ptr->next = pre;
            pre = ptr;
            ptr = next;
        }
        return pre;
    }
    
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        ListNode* dummy = new ListNode(-1);
        dummy->next = head;
        ListNode* first = dummy, * last = dummy, *pre = NULL, *next = NULL, *tmp = NULL;
        while(m--) {
            pre = first;
            first = first->next;
        }
        while(n--) {
            last = last->next;
            next = last->next;
        }
        last->next = NULL;
        tmp = first;
        pre->next = reverseList(tmp);
        first->next = next;
        return dummy->next;
    }
};

143. Reorder List [medium]

Given a singly linked list LL0→L1→…→Ln-1→Ln,
reorder it to: L0→LnL1→Ln-1→L2→Ln-2→…

You may not modify the values in the list's nodes, only nodes itself may be changed.

Example 1:

Given 1->2->3->4, reorder it to 1->4->2->3.

Example 2:

Given 1->2->3->4->5, reorder it to 1->5->2->4->3.
  • 思路:先找到中点。然后把后半部分逆转。然后再合并两个链表。
  • 复杂度:time O(N), space O(1)
/**
 * 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 == NULL || head->next == NULL)
            return head;
        ListNode* pre = NULL, *ptr = head, *next;
        while(ptr) {
            next = ptr->next;
            ptr->next = pre;
            pre = ptr;
            ptr = next;
        }
        return pre;
    }
    void mergeList(ListNode* first, ListNode* second) {
        bool tic = true;
        ListNode* next, *ret = first;
        while(first && second) {
            if (tic) {
                next = first->next;
                first->next = second;
                first = next;
            } else {
                next = second->next;
                second->next = first;
                second = next;
            }
            tic = !tic;
        }
    }
    void reorderList(ListNode* head) {
        if (head == NULL || head->next == NULL)
            return;
        ListNode* slow = head, *fast = head, *second = NULL, *pre = NULL;
        while(fast) {
            pre = slow;
            slow = slow->next;
            fast = fast->next;
            if(fast) {
                fast = fast->next;
            }
        }
        pre->next = NULL;
        second = reverseList(slow);
        ListNode* ptr2 = second;
        mergeList(head, second);
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值