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

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

  • 题目描述
  • 解题思路 & 代码实现

题目描述

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;	
};

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

你可能感兴趣的:(代码随想录二刷,算法,c++)