• 代码随想录训练营day3:链表part1


    理论

    链表的增删操作时间复杂度O(1),查询时间复杂度O(n),因为要从头结点开始。使用场景和数据完全相反
    链表的储存地址是不连续的。也和数组不同。

    移除链表元素

    利用虚拟头结点可以同意操作。不然删除头结点需要额外写。
    记得返回的是虚拟头结点的next而不是虚拟头结点return dummyhead。哈哈哈

    class Solution {
    public:
        ListNode* removeElements(ListNode* head, int val) {
            ListNode* dummyhead = new ListNode(60);
            dummyhead->next=head;
            ListNode* cur=dummyhead;
            while(cur->next!=NULL){
                if(cur->next->val == val){
                    ListNode* temp=cur->next;
                    cur->next = cur->next->next;
                    delete temp;
                }
                else{
                    cur=cur->next;
                }
            }
            return dummyhead->next;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    设计链表

    总是忘记判定插入或者删除的位置是否有效。

    class MyLinkedList {
    public:
        struct ListNode {
            int val;
            ListNode *next;
            ListNode(int val) : val(val), next(nullptr) {}
        };
        MyLinkedList() {
            dummyhead=new ListNode(0);
            size=0;
        }
        
        int get(int index) {
            if(index>size-1)
                return -1;
            ListNode* cur=dummyhead->next;
            for(int i=0;i<index;i++){
                cur=cur->next;
            }
            return cur->val;
        }
        
        void addAtHead(int val) {
            ListNode* head= new ListNode(val);
            head->next=dummyhead->next;
            dummyhead->next=head;
            size++;
        }
        
        void addAtTail(int val) {
            if(size==0) dummyhead->next=new ListNode(val);
            else{
                ListNode* cur=dummyhead->next;
                while(cur->next != NULL){
                    cur=cur->next;
                }
                cur->next= new ListNode(val);
            }
            size++;
        }
        
        void addAtIndex(int index, int val) {
            if(index>size) return;
            ListNode* cur=dummyhead;
            for(int i=0;i<index;i++){
                cur=cur->next;
            }
            ListNode* temp=new ListNode(val);
            temp->next=cur->next;
            cur->next=temp;
            size++;
        }
        
        void deleteAtIndex(int index) {
            if(index>=size) return;
            ListNode* cur=dummyhead;
            for(int i=0;i<index;i++){
                cur=cur->next;
            };
            ListNode* temp=cur->next;
            cur->next=cur->next->next;
            delete temp;
            size--;
        }
    
        //void printLinkedList(){
    
        //}
    private:
        int size;
        ListNode* dummyhead;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    翻转链表

    中间过程想到了用三个指针,双指针+储存临时下一个的指针。
    但是开头和结尾的处理过程没想出来。
    直接让pre=head,这样的话还得加上head->next=nullptr才表示一条链表结束了。
    所以让pre=null就不用特殊处理开头和结尾了。

        ListNode* reverseList(ListNode* head) {
            //if(head->next==nullptr) return nullptr;
            //ListNode* dummyhead= new ListNode(0);
            //dummyhead->next=head;
            //ListNode* pre=head;
            //ListNode* cur=pre->next;
            //ListNode* next=cur->next;
            //cur->next=pre;
            //head=reversal(cur,next);
            //return head;
            if(head==nullptr) return nullptr;
            ListNode* pre=nullptr;
            ListNode* cur=head;
            while(cur!=nullptr){
                ListNode* next=cur->next;
                cur->next=pre;
                pre=cur;
                cur=next;
            }
            return pre;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    快忘记递归怎么写啦,就是递归套递归。

    class Solution {
    private:
        ListNode* reversal(ListNode* pre,ListNode* cur){
            if(cur==nullptr) return pre;
            ListNode* temp=cur->next;
            cur->next=pre;
            return reversal(cur,temp);
        }
    public:
        ListNode* reverseList(ListNode* head) {
            ListNode* pre=nullptr;
            ListNode* cur=head;
            return reversal(pre,cur);
        }
    
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    接口自动化测试之Mock
    模拟卷Leetcode【普通】341. 扁平化嵌套列表迭代器
    Windows与网络基础-17-组策略应用
    苹果电脑构建XLua的arm64-v8a、armeabi-v7a、x86等的so库,
    里奥哈大使撰文 | 来一场云旅行吧,盘点里奥哈那些美轮美奂的酒庄~
    【iOS开发】(六)react Native 路由嵌套传参与框架原理(完)20240423
    MongoDB集群之分片集群 Shard Cluster
    5个月做视频号的心路历程
    【时间之外】EA交易代码入门
    PCL点云处理之点云转为Mesh模型并保存---方法一 (二百一十)
  • 原文地址:https://blog.csdn.net/qq_45789731/article/details/134088968