链表
虚拟头节点的妙用
题目
力扣203. 移除链表元素
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
while (head != nullptr && head->val == val) {
ListNode* temp = head;
head = head->next;
//注意内存管理
delete temp;
}
ListNode* p = head;
while (p && p->next) {
if (p->next->val == val) {
ListNode* temp = p->next;
p->next = p->next->next;
//注意内存管理
delete temp;
} else {
p = p->next;
}
}
return head;
}
};
力扣707. 设计链表
class MyLinkedList {
public:
struct LinkedNode {
int val;
LinkedNode* next;
LinkedNode(int val) : val(val), next(nullptr) {}
};
MyLinkedList() {
_dummyHead = new LinkedNode(0);
_size = 0;
}
int get(int index) {
if (index >= _size || index < 0)
return -1;
LinkedNode* p = _dummyHead->next; // 从第一个实际节点开始
for (int i = index; i > 0; i--) { // 迭代 index 次
p = p->next;
}
return p->val;
}
void addAtHead(int val) {
LinkedNode* newNode = new LinkedNode(val);
newNode->next = _dummyHead->next;
_dummyHead->next = newNode;
_size ++;
}
void addAtTail(int val) {
LinkedNode* p = _dummyHead;
while(p->next){
p = p->next;
}
LinkedNode* temp = new LinkedNode(val);
temp->next = p->next;
p->next = temp;
_size ++;
}
void addAtIndex(int index, int val) {
if(index == _size) addAtTail(val);
else if(index == 0) addAtHead(val);
else if(index > _size) return;
else{
LinkedNode* p = _dummyHead;
for(int i = index - 1; i >= 0; i -- )
p = p->next;
LinkedNode* temp = new LinkedNode(val);
temp->next = p->next;
p->next = temp;
_size ++;
}
}
void deleteAtIndex(int index) {
if (index < 0 || index >= _size)
return;
LinkedNode* p = _dummyHead;
for (int i = 0; i < index; i++)
p = p->next;
LinkedNode* temp = p->next;
p->next = temp->next;
delete temp;
_size--;
}
private:
int _size;
LinkedNode* _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);
*/
力扣206.反转链表
双指针法:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* temp; // 保存cur的下一个节点
ListNode* cur = head;
ListNode* pre = NULL;
while(cur) {
temp = cur->next; // 保存一下 cur的下一个节点,因为接下来要改变cur->next
cur->next = pre; // 翻转操作
// 更新pre 和 cur指针
pre = cur;
cur = temp;
}
return pre;
}
};
递归法:
class Solution {
public:
ListNode* reverse(ListNode* pre,ListNode* cur){
if(cur == NULL) return pre;
ListNode* temp = cur->next;
cur->next = pre;
return reverse(cur,temp);
}
ListNode* reverseList(ListNode* head) {
return reverse(NULL, head);
}
};
虚拟头节点法:
// 迭代方法:增加虚头结点,使用头插法实现链表翻转
public static ListNode reverseList1(ListNode head) {
// 创建虚头结点
ListNode dumpyHead = new ListNode(-1);
dumpyHead.next = null;
// 遍历所有节点
ListNode cur = head;
while(cur != null){
ListNode temp = cur.next;
// 头插法
cur.next = dumpyHead.next;
dumpyHead.next = cur;
cur = temp;
}
return dumpyHead.next;
}