day3_linked_list related(leetcode 206/207/707)

1. Remove Linked List Elements(leetcode 203)

题目:给定一个链表头节点 head 和一个整数 val,删除链表中所有满足 Node.val == val 的节点,并返回新的头节点

最直观的想法就是遍历链表,遇到节点值等于val的节点就删除它,遇到不等于val的节点则保留。需要注意处理头节点可能被删除的情况。

比较基本的操作,考察基本的数据结构理解和代码操作能力。

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        while (head && head->val == val) {
            head = head->next;
        }
        if (!head) return head;
        ListNode* n = head;
        while (n->next) {
            if (n->next->val == val) {
                n->next = n->next->next;
            }
            else {
                n = n->next;
            }
        }
        delete n;
        return head;
    }
};

复杂度分析
  • 时间复杂度: O(n),其中 n 是链表的长度。需要遍历链表一次。
  • 空间复杂度: O(1)

2. Reverse Linked List(leetcode 206)

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

  1. 最初想到的方法是,遍历链表,把每个节点的值存到一个数组里,再从数组从后往前构建一个新链表。这需要O(n)的额外空间。
  2. 更好的方法是原地反转。用三个指针pre,cur,nxt分别表示前一个节点,当前节点和后一个节点,边遍历边反转节点的指向。
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (!head) return head;
        if (head && !head->next) return head; 
        
        vector<int> v;
        ListNode* ptr = head;
        while (ptr) {
            v.push_back(ptr->val);
            ptr = ptr->next;
        }
        
        int size = v.size() - 1;
        ListNode* newHead = new ListNode(v[size]);
        ListNode* cur = newHead;
        for (int i = size - 1 ; i >= 0; i--) {
            cur->next = new ListNode(v[i]);
            cur = cur->next;
        }
        return newHead;
    }
};

Better approach:

class Solution2 {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* prev = nullptr;
        ListNode* curr = head;
        while (curr) {
            ListNode* temp = curr->next;
            curr->next = prev;
            prev = curr;
            curr = temp;
        }
        return prev;
    }
};

3. Design Linked List(Leetcode707)

题目:设计链表的实现。

反思总结:

通过这道题的练习,复习了单链表的基本操作。但在代码实现过程中,还是有些小细节需要注意,比如在插入和删除操作时,需要先找到对应位置的前一个节点。另外在各种操作前,需要判断链表是否为空以及索引是否有效。

总的来说,对链表的操作还不够熟练,还需要多加练习。接下来打算继续练习一些链表相关的题目,如链表的反转、合并等,以加深对链表的理解和应用。同时还要注意培养编码的耐心,养成仔细分析问题的习惯。

class LinkedNode {
public:
    LinkedNode* next;
    int val;
    LinkedNode (int val , LinkedNode* next) : val(val), next(next) {}
    LinkedNode (int val) : val (val) , next(nullptr){}
};

class MyLinkedList {
private:
    LinkedNode* head;

public:
    //constructor
    MyLinkedList(int size, LinkedNode* head) : head(head) {}
    MyLinkedList() : head(nullptr) {}

    int get(int index) {
        if (index < 0 || !head) return -1;//invalid index
        if (index == 0 && head) return head->val;
        LinkedNode* temp = head;
        for (int i = 0; i < index; i++) {
            temp = temp->next;
            if (!temp) return -1;
        }
        return temp->val;

    }

    void addAtHead(int val) {
        LinkedNode* newhead = new LinkedNode(val);
        if (!head) {
            head = newhead;
        }
        else {
            newhead->next = head;
            head = newhead;
        }
    }

    void addAtTail(int val) {
        LinkedNode* tail = new LinkedNode(val);

        if (!head) {
            head = tail;
            return;
        }
        LinkedNode* ptr = head;
        while (ptr->next) {
            ptr = ptr->next;
        }

        ptr->next = tail;
    }

    void addAtIndex(int index, int val) {
        if (index < 0) return;
        if (index == 0) {
            addAtHead(val);
            return;
        }
        int count = 0;
        LinkedNode* temp = head;
        while (count < index - 1 && temp)//loop need to be stoped at index -1 then perform insertion
        {
            temp = temp->next;
            count++;
        }
        if (!temp) return;
        else {
            LinkedNode* ptr = temp->next;
            temp->next = new LinkedNode(val, ptr);
        }
    }

    void deleteAtIndex(int index) {
        if (index < 0 || !head) return;
        if (index == 0) {
            LinkedNode* temp = head;
            head = head->next;
            return;
        }
        int count = 0;
        LinkedNode* ptr = head;
        while (count < index - 1 && ptr) {
            ptr = ptr->next;
            count++;
        }
        if (!ptr || !ptr->next) return;
        else {
            LinkedNode* temp = ptr->next->next;
            ptr->next = temp;
        }
    }


};

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值