• 代码随想录二刷 |链表 | 设计链表


    代码随想录二刷 |链表 | 设计链表

    题目描述

    707.设计链表

    你可以选择使用单链表或者双链表,设计并实现自己的链表。

    单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。

    如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。

    实现 MyLinkedList 类:

    • MyLinkedList() 初始化 MyLinkedList 对象。
    • int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
    • void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
    • void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
    • void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
    • void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。

    示例:

    输入
    [“MyLinkedList”, “addAtHead”, “addAtTail”, “addAtIndex”, “get”, “deleteAtIndex”, “get”]
    [[], [1], [3], [1, 2], [1], [1], [1]]
    输出
    [null, null, null, null, 2, null, 3]

    解释
    MyLinkedList myLinkedList = new MyLinkedList();
    myLinkedList.addAtHead(1);
    myLinkedList.addAtTail(3);
    myLinkedList.addAtIndex(1, 2); // 链表变为 1->2->3
    myLinkedList.get(1); // 返回 2
    myLinkedList.deleteAtIndex(1); // 现在,链表变为 1->3
    myLinkedList.get(1); // 返回 3

    提示:

    0 <= index, val <= 1000
    请不要使用内置的 LinkedList 库。
    调用 get、addAtHead、addAtTail、addAtIndex 和 deleteAtIndex 的次数不超过 2000 。

    解题思路 & 代码实现

    熟悉链表即可。

    class MyLinkedList {
    public:
    	// 定义链表节点结构体
    	struct LinkedNode {
    		int val;
    		LinkedNode* next;
    		LinkedNode(int val) : val(val), next(nullptr) {}
    	};
    	
    	// 初始化链表
    	MyLinkedList() {
    		_dummyHead = new LinkedNode(0);
    		_size = 0;
    	}
    	
    	// 获取第index个节点数值,如果index是非法数值直接返回-1,注意index是从0开始的,第 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++;
    	}
    	
    	// 在第index个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
        // 如果index 等于链表的长度,则说明是新插入的节点为链表的尾结点
        // 如果index大于链表的长度,则返回空
        // 如果index小于0,则在头部插入节点
        void addAtIndex(int index, int val) {
        	if (index > _size) return;
        	if (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++;	
        }
    
        // 删除第index个节点,如果index 大于等于链表的长度,直接return,注意index是从0开始的
        void deleteAtIndex(int index) {
        	if (index >= _size || index < 0) return;
        	LinkedNode* cur = _dummyHead;
        	while (index--) {
        		cur = cur -> next;
        	}
        	LinkedNode* tmp = cur -> next;
        	cur -> next = cur -> next -> next;
        	delete tmp;
        	tmp = nullptr;
        	_size--;
        }
    
    	// 打印链表
    	void printLinkedList() {
    		LinkedNode* cur = _dummyHead;
    		while (cur->next != nullptr) {
    			cout << cur -> next -> val << " ";
    			cur = cur -> next;
    		}
    		cout << endl;
    	}
    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
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    时间复杂度:涉及index的为O(index),其余为O(1)
    空间复杂度:O(1)

  • 相关阅读:
    不重装系统,如何将系统从SSD迁移到M2固态硬盘
    前端笔试记录(三)-代码输出题
    NPDP产品经理知识(产品创新流程)
    kubernetes之Endpoint引入外部资源实践;
    《Java 多线程实战系列》- 01 基本概念与底层原理
    vscode搭建LVGL开发环境
    HTTPS是什么,详解它的加密过程
    Eclipse+Maven+Tomcat 集成开发环境配置
    ython + Selenium Web自动化 2022更新版教程 自动化测试 软件测试 爬虫-笔记博客整理
    hadoop学习:mapreduce的wordcount时候,继承mapper没有对应的mapreduce的包
  • 原文地址:https://blog.csdn.net/jivvv/article/details/134516039