LC.203 | 移除链表元素 | 链表 | 尾插法 |直接遍历

输入:链表 head,整数 val

要求:删除链表中所有值等于 val 的节点,返回新链表的头节点。

输出:删除后链表的头节点。


思路一:直接遍历(原地修改)
  • 使用一个虚拟头结点 dummy,使其 next 指向原始 head。这样做的好处是,即使原始头节点需要被删除,我们也能统一处理,无需特殊判断。
  • 定义一个指针 curdummy 开始遍历。
  • 循环检查 cur->next 节点:
    • 如果 cur->next 的值等于 val,则执行删除操作:cur->next = cur->next->next,直接跳过该节点。
    • 如果值不等于 val,则正常后移指针:cur = cur->next
  • 遍历结束后,返回 dummy->next 即可。

复杂度:

  • 时间复杂度:O(n),n为链表长度。
  • 空间复杂度:O(1)。

思路二:尾插法(构建新链表)
  • 新建一个虚拟头结点 dummy 用于构建新链表,并用一个指针 cur 指向新链表的尾部,初始时 cur = dummy
  • 遍历原始链表(用 head 指针):
    • 如果当前 head 节点的值等于 val,则跳过该节点,仅移动 head = head->next
    • 如果值不等于 val,则将其“摘下”并链接到新链表的尾部:
      1. cur->next = head; // 链接节点
      2. head = head->next; // 原链表指针后移
      3. cur = cur->next; // 新链表尾指针后移
      4. cur->next = NULL; // 关键:断开与原链表后续节点的连接,否则会把不需要的节点也带过来。
  • 遍历结束后,返回 dummy->next

复杂度:

  • 时间复杂度:O(n)。
  • 空间复杂度:O(1),因为我们只是重新组织了原有节点,没有创建新节点。

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        // 思路一:直接遍历(原地修改)
        // ListNode* dummy = new ListNode(0, head); 
        // ListNode* cur = dummy;

        // while (cur->next) { 
        //     if (cur->next->val == val) {
        //         ListNode* del = cur->next;
        //         cur->next = cur->next->next;
        //         delete del; // 在 LeetCode 环境中可以不写 delete
        //     } else {
        //         cur = cur->next;
        //     }
        // }
        // return dummy->next;

        // 思路二:尾插法(构建新链表)
        ListNode* dummy = new ListNode(0, NULL);
        ListNode* cur = dummy;
        while (head) {
            if (head->val == val) {
                // 如果是目标值,直接跳过,原链表指针后移
                head = head->next;
            }
            else {
                // 如果不是目标值,接到新链表尾部
                cur->next = head;
                head = head->next;
                cur = cur->next;
                cur->next = NULL; // 断开链接
            }
        }
        return dummy->next;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值