0%

LeetCode Day7

LeetCode Day7

链表

链表理论基础

1
2
3
4
5
6
7
8
9
// 单链表
struct ListNode {
int val; // 节点上存储的元素
ListNode *next; // 指向下一个节点的指针
ListNode(int x) : val(x), next(NULL) {} // 节点的构造函数
};

// 使用构造函数初始化节点
ListNode* head = new ListNode(5);

移除链表元素

avatar

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
/**
* 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* dummyHead = new ListNode(0, head);
ListNode* temp = dummyHead;
while (temp->next != NULL) {
if (temp->next->val == val) {
ListNode* del = temp->next;
temp->next = temp->next->next;
delete(del);
}
else {
temp = temp->next;
}
}
head = dummyHead->next;
delete dummyHead;
return head;
}
};

/*
* 注意题设中的 head 头结点
* 不是真正的头结点,而是链表的第一个结点
* 考虑到可能删掉所有的结点,有必要设置一个头结点
* 但是返回的时候是返回题设所要求的头结点
* 然后就是注意手动释放内存
*/

avatar

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
/* 直接用题设的 head,那么涉及到 head 的操作就要单独处理 */
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
// 删除头结点
while (head != NULL && head->val == val) { // 注意这里不是if
ListNode* tmp = head;
head = head->next;
delete tmp;
}

// 删除非头结点
ListNode* cur = head;
while (cur != NULL && cur->next!= NULL) {
if (cur->next->val == val) {
ListNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
} else {
cur = cur->next;
}
}
return head;
}
};

设计链表

avatar

avatar

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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
class MyLinkedList {
public:
// 定义链表结点结构体
struct LinkedNode
{
int val;
LinkedNode* next;
LinkedNode(int val) : val(val), next(nullptr) {}
};

// 初始化链表
MyLinkedList() {
_dummyHead = new LinkedNode(0);
_size = 0;
}

// 获取到第 index 个结点数值
int get(int index) {
if (index > _size - 1 || index < 0) return -1;
int cnt = -1;
LinkedNode* temp = _dummyHead;
while (cnt < index) {
temp = temp->next;
cnt++;
}
return temp->val;
}

// 头插
void addAtHead(int val) {
LinkedNode* newNode = new LinkedNode(val);
newNode->next = _dummyHead->next;
_dummyHead->next = newNode;
_size++;
}

// 尾插
void addAtTail(int val) {
LinkedNode* temp = _dummyHead;
LinkedNode* newNode = new LinkedNode(val);
while (temp->next != NULL) {
temp = temp->next;
}
temp->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;
if (index == _size) {
addAtTail(val); return;
}
LinkedNode* temp = _dummyHead;
LinkedNode* newNode = new LinkedNode(val);
int cnt = 0;
while (cnt < index) {
temp = temp->next;
cnt++;
}
newNode->next = temp->next;
temp->next = newNode;
_size++;
}

// 删除第 index 个结点,如果 index 大于等于链表的长度,直接 return
void deleteAtIndex(int index) {
if (index < 0 || index > _size - 1) return;
LinkedNode* temp = _dummyHead;
int cnt = 0;
while (cnt < index) {
temp = temp->next;
cnt++;
}
LinkedNode* del = temp->next;
temp->next = temp->next->next;
delete(del);
// delete 命令指示释放了 del 指针原本所指的那部分内存,
// 被 delete 后的指针 del 的值(地址)并非就是 NULL,而是随机值。也就是被 delete 后,
// 如果不再加上一句 del = nullptr,del 会成为乱指的野指针
// 如果之后的程序不小心使用了 del,会指向难以预想的内存空间
del = nullptr;
_size--;
}

private:
int _size;
LinkedNode* _dummyHead;
// 这里的 _dummyHead 才是一般数据结构中描述的头结点
};

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

/* 测试程序 */
int main()
{
MyLinkedList* myLinkedList = new MyLinkedList();
myLinkedList->addAtHead(1);
myLinkedList->addAtTail(3);
myLinkedList->addAtIndex(1, 2); // 链表变为 1->2->3
cout << myLinkedList->get(1) << endl; // 返回 2
myLinkedList->deleteAtIndex(1); // 现在,链表变为 1->3
cout << myLinkedList->get(1) << endl; // 返回 3
return 0;
}