代码随想录算法【Day3】

发布于:2025-02-11 ⋅ 阅读:(69) ⋅ 点赞:(0)

Day3

1.语法不熟悉,得多练习,反复写

2.虚拟头结点的使用可以让代码更加简洁

203.移除链表元素

头结点的删除和其他节点的删除不一样:删除其他节点,都需要更新其前一个节点的指针,删除头结点,只用把head指针指向下一个节点。所以写代码要分为删除头结点和删除非头结点来写。

有没有一个办法让所有节点的删除方式相同?虚拟头节点

直接删除

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        //删除头结点
        while(head != NULL && head -> val == val){
            ListNode* tmp = head;
            head = head -> next;
            delete tmp;
        }
        //删除非头结点
        ListNode *cur = head;
        while(cur != NULL && cur -> next != NULL){
            if(cur -> next -> val == val){
                ListNode* tmp = cur -> next;
                cur -> next = cur -> next -> next;
                delete tmp;
            }
            else{
                cur = cur -> next;
            }
        }
        return head;
    }
};

使用虚拟头结点

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        //创建虚拟头结点
        ListNode* dummyHead = new ListNode(0);
        dummyHead -> next = head;
        ListNode* cur = dummyHead; 
        while(cur != NULL && cur -> next != NULL){
            if(cur -> next -> val == val){
                ListNode *tmp = cur -> next;
                cur -> next = cur -> next -> next;
                delete tmp;
            }
            else{
                cur = cur -> next;
            }
        }
        head = dummyHead -> next;
        delete dummyHead; //记得回收空间,第一次写忘掉了
        return head;
    }
};
707.设计链表

addAtIndex方法的描述不太好理解,如下举例说明:

假设初始链表为 [1, 2, 3]

情况 1:index = 1, val = 5

  • 新节点 5 插入到下标 1 的位置之前,原链表的第 1 个节点是 2

  • 插入后链表变为 [1, 5, 2, 3]

情况 2:index = 3, val = 7

  • 插入后链表变为 [1, 2, 3, 7]

情况 3:index = 5, val = 9

  • 链表长度为 3index = 5 超过了长度,不进行任何插入操作,链表保持 [1, 2, 3]

情况 4:index = 0, val = 4

  • 下标 0 是链表的开头位置,新节点 4 会成为新的头节点。

  • 插入后链表变为 [4, 1, 2, 3]

class MyLinkedList {
public:
    //定义链表节点结构体
    struct LinkedNode{
        int val;
        LinkedNode* next;
        LinkedNode(int val):val(val), next(nullptr){}//nullptr是C++中的关键字,表示空指针
    };
    //初始化MyLinkedList对象
    MyLinkedList() {
        _dummyHead = new LinkedNode(0); //虚拟头结点
        _size = 0;
    }
    //获取第index个节点的值,无效则返回-1,节点从0开始
    int get(int index) {
        if(index > (_size-1) || index < 0) return -1;
        LinkedNode* cur = _dummyHead -> next;
        while(index--){
            cur = cur -> next;
        }
        return cur -> val;
    }
    //头插法
    void addAtHead(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        newNode -> next = _dummyHead -> next;
        _dummyHead -> next = newNode;
        _size ++;
    }
    //尾插法
    void addAtTail(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = _dummyHead;
        while(cur -> next != nullptr){
            cur = cur -> next;
        }
        cur -> next = newNode;
        _size ++;
    }
    
    void addAtIndex(int index, int val) {
        if(index > _size) return;
        if(index < 0) index = 0;//把index小于0的情况也看作头插法
        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = _dummyHead;
        while(index --){
            cur = cur -> next;
        }
        newNode -> next = cur -> next;
        cur -> next = newNode;
        _size++;
    }
    
    void deleteAtIndex(int index) {
        if(index > _size - 1 || index < 0) return;
        LinkedNode *cur = _dummyHead;
        while(index --){
            cur = cur -> next;
        }
        LinkedNode *temp = cur -> next;
        cur -> next = cur -> next -> next;
        delete temp;
        _size --;
    }
​
    void printLinkedList(){
        LinkedNode* cur = _dummyHead;
        while(cur -> next != nullptr){
            cout << cur->next ->val << " ";
            cur = cur -> next;
        }
        cout << endl;
    }
private:
    int _size;
    LinkedNode* _dummyHead;
};
​
206.反转链表

双指针法:

网站上的动图很形象。

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* pre = NULL;
        ListNode* cur = head;
        ListNode* tmp;
        while(cur != NULL){
            tmp = cur -> next;
            cur -> next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }
};

递归写法:

class Solution {
public:
    ListNode* reverse(ListNode* cur, ListNode* pre) {
       //递归终止的条件
       if(cur == NULL) return pre;
       ListNode* tmp = cur -> next;
       cur -> next = pre;
       return reverse(tmp, cur);
    }
    ListNode* reverseList(ListNode* head) {
       return reverse(head, NULL);
    }
};

网站公告

今日签到

点亮在社区的每一天
去签到