代码随想录算法训练营第三天| 203.移除链表元素 707.设计链表 206.反转链表

203.移除链表元素

链表定义

struct ListNode
{
    int val;
    ListNode* next;
    ListNode(): val(0), next(NULL) {};
    ListNode(int x): val(x), next(NULL) {};
    ListNode(int x, ListNode* next): val(x), next(next) {};
}

1.在原链表上移除链表元素

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)
        {
            if(cur->next != NULL && cur->next->val == val)
            {
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            }
            else
                cur = cur->next;
        }

        return head;
    }
};

为什么是

if(cur->next != NULL && cur->next->val == val)

而不是

if(cur->next->val == val)

考虑一个例子,4->5->6,

要删除6的话,到最后一步,cur->next是NULL,访问cur->next->val会报空指针错误

指针

ListNode* node;

这个node里面储存的就是地址了,所以可以有以下操作

ListNode* head
ListNode* node;
node = head

-> 和 .

箭头(->):左边必须为指针;
点号(.):左边必须为实体。

//实体
ListNode node1;
node1.val = 2;
//指针
ListNode node2;
node2->val = 2;

NULL

NULL就是传说中的空指针

delete

delete ptr -- 代表用来释放内存,且只用来释放ptr指向的内存。

ptr为指针

2.添加虚拟头结点法

/**
 * 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* dummy_head;
        ListNode* dummy_head = new ListNode();
        dummy_head->next = head;

        ListNode* cur = dummy_head;
        while(cur != NULL)
        {
            if(cur->next != NULL && cur->next->val == val)
            {
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            }
            else
                cur = cur->next;
        }

        //return head;
        return dummy_head->next;
    }
};

为什么是

ListNode* dummy_head = new ListNode();

而不是

ListNode* dummy_head;

错误原因:没有实例化,而接下来的代码里要调用dummy_head里的东西,所以会报错

为什么是

return dummy_head->next;

而不是

return head;

因为之前的head有可能被释放掉了

707.设计链表

mydemo-未添加内存释放

class MyLinkedList {
public:
    //结点结构体
    struct LinkedNode {
        int val;
        LinkedNode* next;
        LinkedNode(): next(NULL) {};
        LinkedNode(int val):val(val), next(NULL){};
    };
    
    LinkedNode* dummyhead;
    int size;

    MyLinkedList() {
        dummyhead = new LinkedNode(); //不要忘记实例化
        size = 0;
    }
    
    int get(int index) {
        LinkedNode* cur = dummyhead;
        
        if(index>=0 && index<size)
        {
            while(index--)
                cur = cur->next;
            return cur->next->val;
        }
        else
            return -1;
    }
    
    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 != NULL)
        { 
           cur = cur->next;
        }

        cur->next = newnode;
        size++;
    }
    
    void addAtIndex(int index, int val) {
        LinkedNode* newnode = new LinkedNode(val);
        LinkedNode* cur = dummyhead;

        if(index>=0 && index<=size)
        {
            while(index--)
            {
                cur = cur->next;
            }

            newnode->next = cur->next;
            cur->next = newnode;
            size++;
        }
    }
    
    void deleteAtIndex(int index) {

        LinkedNode* cur = dummyhead;
        
        if(index>=0 && index<size)
        {
            while(index--)
            {
                cur = cur->next;
            }
            cur->next = cur->next->next;
            size--;
        }
    }
};

/**
 * 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);
 */

mydemov2--内存释放版

    void deleteAtIndex(int index) {

        LinkedNode* cur = dummyhead;
        
        if(index>=0 && index<size)
        {
            while(index--)
            {
                cur = cur->next;
            }

            LinkedNode* tmp = cur->next;
            cur->next = cur->next->next;
            size--;

            //内存释放
            delete tmp;
        }
    }

206 反转链表

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* reverseList(ListNode* head) {
            
            ListNode* pre = NULL;
            ListNode* cur = head;

            while(cur != NULL) //可以写成 while(cur)
            {
                ListNode* temp = cur->next;
                cur->next = pre;
                pre = cur;
                cur = temp;
            }

            return pre;
    }
};

暂存cur->next;

ListNode* temp = cur->next;

key:改变方向

cur->next = pre;

双指针向前移动(注意顺序)

pre = cur;
cur = temp;

如果顺序搞错了:

cur = temp;
pre = cur
//pre移动到的就不是cur之前的位置了,就错了

2.递归代码:

正确代码:

/**
 * 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* reverse(ListNode* cur, ListNode* pre)
    {
        if(cur==NULL)   return pre;
        
        ListNode* temp = cur->next;
        cur->next = pre;
        return reverse(temp, cur);
    }

    ListNode* reverseList(ListNode* head) {
        
        ListNode* pre = NULL;
        ListNode* cur = head;

        return reverse(cur, pre);
    }
};

报错:C++不能函数里面定义函数

/**
 * 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* pre = NULL;
            ListNode* cur = head;

            void reverse(ListNode* cur, ListNode* pre)
            {
                if(cur)
                {
                    ListNode* temp = cur->next;
                    cur->next = pre;
                    pre = cur;
                    cur = temp;
                }
            }

            reverse(cur, pre);
            return pre;
    }
};

Line 19: Char 13: error: function definition is not allowed here

报错:为啥这样写,所有案例的输出都是 []

/**
 * 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) {}
 * };
 */
void reverse(ListNode* cur, ListNode* pre);

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
            
            ListNode* pre = NULL;
            ListNode* cur = head;
    
            reverse(cur, pre);
            return pre;
    }
};

void reverse(ListNode* cur, ListNode* pre)
{
    if(cur)
    {
        ListNode* temp = cur->next;
        cur->next = pre;
        pre = cur;
        cur = temp;
        reverse(cur,pre);
    }
}
  1. 链表的结构确实发生了反转,但是,reverseList函数里的pre指针并没有被重新赋值成反转链表的pre的地址。
  2. void reverse(ListNode* cur, ListNode* pre),这样传进去的是地址

所以可以改写成reverse(head, Null)可以更加清晰的看到传进去的是地址,所以pre并没有被重新赋值

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
            
            ListNode* pre = NULL;
            ListNode* cur = head;
    
            //reverse(cur, pre);
        	reverse(head, NULL);
            return pre;
    }
};
posted @ 2023-09-09 10:40  zz子木zz  阅读(205)  评论(0编辑  收藏  举报