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]

​ 解释

1
2
3
4
5
6
7
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、addAtIndexdeleteAtIndex的次数不超过 2000 。

​ 来源:力扣(LeetCode) ​ 链接:https://leetcode.cn/problems/design-linked-list

思路

​ 采用设置哨兵节点作为头节点可简化操作。

实现代码

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
class MyLinkedList {
public:
MyLinkedList() {
this->m_size = 0;
this->m_head = new ListNode(0);
}

int get(int index) {
if (index < 0 || index >= m_size) {
return -1;
}
ListNode* currrentNode = m_head;
for (int i = 0; i <= index; i++) {
currrentNode = currrentNode->next;
}
return currrentNode->val;
}

void addAtHead(int val) {
addAtIndex(0, val);
}

void addAtTail(int val) {
addAtIndex(m_size, val);
}

void addAtIndex(int index, int val) {
if (index > m_size) {
return;
}
m_size++;
ListNode* pred = m_head;
for (int i = 0; i < index; i++) {
pred = pred->next;
}
ListNode* newNode = new ListNode(val);
newNode->next = pred->next;
pred->next = newNode;
}

void deleteAtIndex(int index) {
if (index < 0 || index >= m_size) {
return;
}
m_size--;
ListNode* pred = m_head;
for (int i = 0; i < index; i++) {
pred = pred->next;
}
ListNode* p = pred->next;
pred->next = pred->next->next;
delete p;
}
private:
int m_size;
ListNode* m_head;
};

把输入转换成C++代码

​ 为了更方便本地调试代码,这里有一份C++代码可以用来专门实现此目的。

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
#include <iostream>
#include <vector>
#include <sstream>
#include <fstream>

using namespace std;

int main() {
// 打开输入文件
ifstream input_file("input.txt");
if (!input_file) {
cout << "Failed to open file!" << endl;
return 1;
}

// 读取输入文件
string line;
getline(input_file, line);
vector<string> commands;
// 解析命令
line = line.substr(line.find("[") + 1, line.find("]") - 1);
line.erase(remove(line.begin(), line.end(), '\"'), line.end());
stringstream codeStream(line);
string code_str;
while (getline(codeStream, code_str, ',')) {
commands.push_back(code_str);
}
vector<vector<int>> parameters;
string subline;
getline(input_file, line);
line = line.substr(line.find("[") + 1, line.rfind("]") - 1);
line = line.substr(line.find(",") + 1, line.size());
// 解析参数
while (line.find("[") != string::npos)
{
subline = line.substr(line.find("[") + 1, line.find("]") - 1);
line.erase(line.find("["), line.find("]") + 2);
stringstream ss(subline);
string param_str;
vector<int> params;
while (getline(ss, param_str, ',')) {
params.push_back(stoi(param_str));
}
parameters.push_back(params);
}

// 将输入转换为 C++ 代码
stringstream code;
code << "MyLinkedList myLinkedList = new MyLinkedList();\n";
for (int i = 1; i < commands.size(); i++) {
if (commands[i] == "addAtHead") {
code << "myLinkedList.addAtHead(" << parameters[i - 1][0] << ");\n";
}
else if (commands[i] == "addAtTail") {
code << "myLinkedList.addAtTail(" << parameters[i - 1][0] << ");\n";
}
else if (commands[i] == "addAtIndex") {
code << "myLinkedList.addAtIndex(" << parameters[i - 1][0] << ", " << parameters[i - 1][1] << ");\n";
}
else if (commands[i] == "get") {
code << "myLinkedList.get(" << parameters[i - 1][0] << ");\n";
}
else if (commands[i] == "deleteAtIndex") {
code << "myLinkedList.deleteAtIndex(" << parameters[i - 1][0] << ");\n";
}
}

// 打印 C++ 代码
cout << "Code:\n" << code.str() << endl;

return 0;
}

本文封面图片由wal_172619Pixabay上发布