60天刷题记录Day3|链表

42 阅读2分钟

Leetcode 203. Remove Linked List Elements

删除节点:p->next = p->next->next
本题还需要考虑到头节点值为val的情况,所以设置一个虚拟头节点dum,让原来的头节点变为一般情况。最后结果只要返回dum->next就可以了。

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* dum = new ListNode(0);
        dum->next = head;
        auto p = dum;
        while(p->next != NULL){
            if(p->next->val == val){
                p->next = p->next->next;
            }else{
                p = p->next;
            }
        }
        return dum->next;
    }
};

Leetcode 707. Design Linked List

这道题涵盖了链表的常见操作,如果一时想不明白可以找在纸上画一画便于理解。

class MyLinkedList {
public:
    struct Node {
        int val;
        Node* next;
        Node(int _val): val(_val), next(NULL) {};
    }*head;
    MyLinkedList() {
       head = NULL;
    }
    
    int get(int index) {
        if(index < 0) return -1;
        auto p = head;
        for(int i = 0; i < index && p; i ++) p = p->next;
        if(!p) return -1;
        return p->val;
    }
    
    void addAtHead(int val) {
        auto cur = new Node(val);
        cur->next = head;
        head = cur;
    }
    
    void addAtTail(int val) {
        if(!head) head = new Node(val);
        else{
            auto p = head;
            while(p->next) p = p->next;
            p->next = new Node(val);
        }
    }
    
    void addAtIndex(int index, int val) {
        if(index <= 0) addAtHead(val);
        else{
            int len = 0;
            for(auto p = head; p; p = p->next) len ++;
            if(index == len) addAtTail(val);
            else if(index < len){
                auto p = head;
                for(int i = 0; i < index - 1; i ++) p = p->next;
                auto cur = new Node(val);
                cur->next = p->next;
                p->next = cur;
            }
        }
    }
    
    void deleteAtIndex(int index) {
        int len = 0;
        for(auto p = head; p; p = p->next) len ++;
        if(index >= 0 && index < len){
            if(!index) head = head->next;
            else{
                auto p = head;
                for(int i = 0; i < index - 1; i ++) p = p->next;
                p->next = p->next->next;
            }
        }
    }
};

Leetcode 206. Reverse Linked List

翻转即将所有节点的next指针指向前驱节点。 由于是单链表,我们在迭代时不能直接找到前驱节点,所以我们需要一个额外的指针保存前驱节点。同时在改变当前节点的next指针前,不要忘记保存它的后继节点。

空间复杂度分析:遍历时只有3个额外变量,所以额外的空间复杂度是O(1)
时间复杂度分析:只遍历一次链表,时间复杂度是O(n)

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(!head || !head->next) return head;
        auto p = head, q = p->next;
        while(q){
            auto o = q->next;
            q->next = p;
            p = q, q = o;
        }
        head->next = NULL;
        return p;
    }
};