16.哀家要长脑子了!

目录

1. 707. 设计链表 - 力扣(LeetCode)

2.203. 移除链表元素 - 力扣(LeetCode)

3.206. 反转链表 - 力扣(LeetCode)

4.237. 删除链表中的节点 - 力扣(LeetCode)

5. 19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)


1. 707. 设计链表 - 力扣(LeetCode)

这我都懂,但是,一让我动手写代码我就不会了TAT TAT TAT TAT TAT TAT

class MyLinkedList {
    int size;          //链表长度
    ListNode *head;    //头结点
public:
    MyLinkedList() {
        this->size = 0;                  //初始化链表无元素,长度为0
        this->head = new ListNode(0);    //头结点为空
    }
    
    int get(int index) {
        if(index < 0 || index >= size){    //访问位置不合理
            return -1;
        }
        ListNode *p = head;
        for(int i = 0; i <= index; i++){    
            p = p->next;
        }
        return p->val;
    }
    
    void addAtHead(int val) {
        addAtIndex(0,val);
    }
    
    void addAtTail(int val) {
        addAtIndex(size,val);
    }
    
    void addAtIndex(int index, int val) {
        if(index > size){    //插入位置大于链表长度,不合法
            return;
        }
        index = max(0,index);    
        size++;               // 插入元素,长度增加
        ListNode *p = head;
        for(int i = 0; i <index; i++){
            p = p->next;
        }
        ListNode *e = new ListNode(val);
        e->next = p->next;    //先为前驱
        p->next = e;          //再后继
    }
    
    void deleteAtIndex(int index) {
        if(index < 0 || index >= size){
            return ;
        }
        size--;    //删除元素 长度减小
        ListNode *pre = head;
        for(int i = 0; i <index; i++){
            pre = pre->next;    //定位到要删除元素的前一个元素
        }    
        ListNode *p = pre->next;
        pre->next = pre->next->next;    
        delete p;
    }
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */
2.203. 移除链表元素 - 力扣(LeetCode)

用一个空结点当头结点呀~~ 这样子如果需要删除的是头结点的话,就不需要进行额外操作了。

/**
 * 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) {
        ListNode *first = new ListNode(0);    //是要生成新结点不是生成指针
        first->next = head;
        ListNode *p = first;   //工作指针p从头结点开始遍历
        while(p->next){
            if(p->next->val == val){    //p判断下一个位置的值
                p->next = p->next->next;
            }
            else{
                p=p->next;
            }
        }
        head = first->next;    
        delete first;
        return head;
    }
};
3.206. 反转链表 - 力扣(LeetCode)


晕头转向晕头转向



按顺序来是:蓝色、红色、粉色

/**
 * 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 *prev = nullptr;
        ListNode *cur = head;    //用来指向当前反转方向的元素
        while(cur){              //当前元素不为空,就需要反转  
            ListNode *next = cur->next;    //先记录下一个需要反转的元素 
             cur->next = prev;    //反转方向啦!不是指向后一个而是前一个
            prev = cur;      //因为要继续遍历 那么现在的元素对于下一个来说就是前驱元素
            cur = next;      //下一个元素来了  
        }
        return prev;
    }
};

反转链表用三个指针:

用一个pre指针指向空结点,最后反转链表后的pre所指向的头结点就是pre所指向的指针,cur指向要转换方向的两个结点中的第一个结点,next指向要转换方向的两个结点中的第二个结点。每次循环改变第一个结点的方向

循环:首先定位好next,然后转换第一个结点的的方向,使cur指向pre。转换好方向后,迭代指针,将pre向后移动,指向cur,因为cur就在pre的下一位。cur向后移动,指向next,因为next就在cur的下一位。然后在下一个循环的开始又会重新定位好next,因为next要在cur的下一位呀。最后循环结束的时候,cur会指向空(最后一个结点的下一位)。pre则指向的是最后一个结点,按道理来说是第一个结点。

4.237. 删除链表中的节点 - 力扣(LeetCode)


嗯。。。。看不太懂题,后面看题解发现,题目中给出这个哪个结点就删除哪个结点,不会给出整个链表,那你直接对这个结点操作就好。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void deleteNode(ListNode* node) {
        node->val = node->next->val;    //记得要把值也给更改了
        node->next = node->next->next;
    }
};
5. 19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

下次想到办法就先自己动手试试,不管会不会,先试试,再去看题解,像这个你自己的思路就是对的,要自信呀

单链表要删除结点,但是又不知道是正数第几个,没办法咯,只能先求出链表长度。

然后倒数第n个结点就是正数第length-n+1个结点。

/**
 * 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* removeNthFromEnd(ListNode* head, int n) {
        ListNode *p = head;
        int length = 0;
        while(p){
            ++length;
            p = p->next;
        } 
        ListNode *dummy = new ListNode(0, head);
        p = dummy;
        int m = length - n + 1;
        for(int i = 0; i < m-1; i++){
            p = p->next;
        }
        p->next = p->next->next;
        ListNode *ans = dummy->next;
        delete dummy;
        return ans;
    }
};

对于所要删除的结点的前驱结点的定位

for(int i = 1; i < m; i++) 或 for(int i = 0; i < m-1; i++)

加油! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值