今日任务
203.移除链表元素
先将头部连续的val节点删除,实际工程中记得释放堆空间
/**
* 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) {}
* };
*/
// #define _DELETE_HEAP
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
#ifdef _DELETE_HEAP
ListNode *tmp;
#endif
while (head && head->val == val) {
#ifdef _DELETE_HEAP
tmp = head;
#endif
head = head->next;
#ifdef _DELETE_HEAP
delete tmp;
#endif
}
ListNode *newHead = head, *p = head;
while (p) {
while (p->next && p->next->val == val) {
#ifdef _DELETE_HEAP
tmp = p->next;
#endif
p->next = p->next->next;
#ifdef _DELETE_HEAP
delete tmp;
#endif
}
p = p->next;
}
return newHead;
}
};
707.设计链表
没啥难度,但是注意节点判空等细节,然后可以使用虚拟头节点来简化程序
// #define _DEBUG
struct LinkNode {
int val = -1;
LinkNode *prev = nullptr, *next = nullptr;
LinkNode() = default;
LinkNode(int _val, LinkNode *_prev = nullptr, LinkNode *_next = nullptr) : val(_val), prev(_prev), next(_next) {}
};
class MyLinkedList {
public:
MyLinkedList() {
dummyHead = new LinkNode();
dummyTail = new LinkNode();
dummyHead->next = dummyTail;
dummyTail->prev = dummyHead;
}
int get(int index) {
if (index < 0 || index >= size) return -1;
LinkNode *pCur = dummyHead->next;
while (index--) {
pCur = pCur->next;
}
return pCur->val;
#ifdef _DEBUG
print();
#endif
}
void addAtHead(int val) {
LinkNode *p = new LinkNode(val);
// 先在链外以p为节点接一根线
p->prev = dummyHead;
p->next = dummyHead->next;
// 再把链内原来的线重新接到p上
dummyHead->next->prev = p;
dummyHead->next = p;
++size;
#ifdef _DEBUG
print();
#endif
}
void addAtTail(int val) {
LinkNode *p = new LinkNode(val);
p->next = dummyTail;
p->prev = dummyTail->prev;
dummyTail->prev->next = p;
dummyTail->prev = p;
++size;
#ifdef _DEBUG
print();
#endif
}
void addAtIndex(int index, int val) {
if (index > size) return ;
else if (index < 0) addAtHead(val);
else if (index == size) addAtTail(val);
else {
LinkNode *pCur = dummyHead->next;
while (index--) { // 0的时候不进入循环,因为pCur初始值为第0个节点
pCur = pCur->next;
}
// 前插
LinkNode *p = new LinkNode(val);
p->prev = pCur->prev;
p->next = pCur;
pCur->prev->next = p;
pCur->prev = p;
++size;
}
#ifdef _DEBUG
print();
#endif
}
void deleteAtIndex(int index) {
if (index >= 0 && index < size) {
LinkNode *pCur = dummyHead->next;
while (index--) { // 0的时候不进入循环,因为pCur初始值为第0个节点
pCur = pCur->next;
}
pCur->prev->next = pCur->next;
pCur->next->prev = pCur->prev;
delete pCur;
--size;
}
#ifdef _DEBUG
print();
#endif
}
void print() {
if (size == 0) return ;
LinkNode *p = dummyHead->next;
while (p != dummyTail) {
cout << p->val << ' ';
p = p->next;
}
cout << "size = " << size;
cout << endl;
}
private:
LinkNode *dummyHead, *dummyTail;
int size = 0;
};
/**
* 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);
*/
206.反转链表
方法一:遍历头插法
/**
* 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* reverseList(ListNode* head) {
ListNode *tmp = nullptr, *newHead = nullptr;
while (head) {
tmp = head;
head = head->next;
tmp->next = newHead;
newHead = tmp;
}
return newHead;
}
};
方法二:改成递归版本头插法
1.原始递归
class Solution {
public:
// 递归写法
ListNode* reverse(ListNode* newHead, ListNode* cur) {
if (cur == nullptr) return newHead;
ListNode *tmp = cur;
cur = cur->next;
tmp->next = newHead;
return reverse(tmp, cur);
}
ListNode* reverseList(ListNode* head) {
return reverse(nullptr, head);
}
};
2.简化版递归
/**
* 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* reverse(ListNode *newHead, ListNode* cur) {
if (cur == nullptr) return newHead;
ListNode* tmp = cur->next;
cur->next = newHead;
return reverse(cur, tmp);
}
ListNode* reverseList(ListNode* head) {
return reverse(nullptr, head);
}
};