算法训练营第三天(7.14)| 链表Part01

目录

LeeCode203. Remove Linked List Elements

 LeeCode707. Design Linked List

 LeeCode206. Reverse Linked List


LeeCode203. Remove Linked List Elements

题目地址:力扣

题目类型:无头单链表

算法训练营第三天(7.14)| 链表Part01_第1张图片

 思路:构建两个指针p&q,p的next指向q,依次遍历,若q的val等于val,则删除q。

要注意的点是第一个元素也可能要删除,故构造一个头节点h来标识,最后返回h的next即可。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        // h固定为链表头节点,使用head对链表进行遍历,并使用p对head的前一个及进行标记
        ListNode* h = new ListNode(),* p = new ListNode();
        h->next = head;
        p = h;
        while (head != nullptr) {
            if (head->val == val) {
                p->next = head->next;
                delete(head);
            }
            else p = head;
            head = p->next;
        }
        return h->next;
    }
};

 LeeCode707. Design Linked List

题目地址:力扣

题目类型:设计题

算法训练营第三天(7.14)| 链表Part01_第2张图片算法训练营第三天(7.14)| 链表Part01_第3张图片

思路:按照题目要求设计就好了

注意问题

  • 在本题中我设置了一个head头节点来简化对链表的一系列操作,但是需要注意index的取值
  • 在函数deleteAtIndex中,如果要删除最后一个节点,应当修改tail尾指针,否则会出先野指针
struct node {
    node* next;
    int val;
    node() {}
    node(int w) {
        next = nullptr;
        val = w;
    }
};

class MyLinkedList {
private:
    int len;
    node* head;
    node* tail;
public:
    MyLinkedList() {
        head = new node();
        tail = head;
        len = 0;
    }
    
    int get(int index) {
        // 如果超过长度
        if (index + 1 > len) return -1;
        int i = -1;
        node* p = head;
        while (i != index) {
            p = p->next;
            i++;
        } 
        
        return p->val;
    }
    
    void addAtHead(int val) {
        node* p = new node(val);
        p->next = head->next;
        head->next = p;
        len++;
        if (tail == head) tail = head->next;
    }
    
    void addAtTail(int val) {
        node* p = new node(val);
        p->next = tail->next;
        tail->next = p;
        tail = tail->next;
        len++;
    }
    
    void addAtIndex(int index, int val) {
        cout< len) return;
        node* p = head, *q = new node(val);
        int i = 0;
        while (i < index) {
            p = p->next;
            i++;
        }
        q->next = p->next;
        p->next = q;
        len++;
        if (index + 1 == len) tail = tail->next;
    }
    
    void deleteAtIndex(int index) {
        // 如果大于长度了
        if (index + 1 > len) return;
        node* p = head;
        int i = 0;
        while (i < index) {
            p = p->next;
            i++;
        }
        // 如果要删除最后一个元素,一定要给tail尾指针重新赋值,否则会产生野指针
        if (index + 1 == len) tail = p;
        if (p->next != nullptr) p->next = p->next->next;
        len--;
    }
};

 LeeCode206. Reverse Linked List

题目地址:力扣

题目类型:单链表

算法训练营第三天(7.14)| 链表Part01_第4张图片

 思路:定义新的头节点h,顺序遍历head,依次头插到h中。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* h = new ListNode();
        while (head != nullptr) {
            ListNode* q = new ListNode(head->val);
            q->next = h->next;
            h->next = q;
            head = head->next;
        }
        return h->next;
    }
};

在design linked list那道题中,因为tail的野指针问题,被卡了很久,结果到最后是因为一个等号写错了,还是要再仔细一点!

你可能感兴趣的:(算法训练营,算法,链表,数据结构,c++,学习)