203. 移除链表元素
题目中传入的链表没有头结点,为了统一操作(当第一个结点是被删除节点时,没有头结点的链表需要单独处理),创建一个虚拟头结点指向当前链表第一个结点。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
1
)
O(1)
O(1)
// c++
/**
* 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();
dummyHead->next = head;
ListNode *pre = dummyHead, *p = head;
while(p){
if(p->val == val) {
pre->next = p->next;
delete p;
p = pre->next;
continue;
}
p=p->next;
pre=pre->next;
}
return dummyHead->next;
}
};
不额外加头结点写法:
// c++
/**
* 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 *p = head, *pre=nullptr;
while(p && p->val == val){
head = head->next;
delete p;
p = head;
}
while(p){
if(p->val == val) {
pre->next = p->next;
delete p;
p = pre->next;
continue;
}
pre=p;
p=p->next;
}
return head;
}
};
707. 设计链表
这是一个链表的增删查操作。为了方便操作,设计一个带有头结点的单链表,为实现这一操作,额外定义一个链表节点。在类中添加头结点和链表长度属性。
// c++
struct Node{
int val;
Node* next;
/*
Node() : val(0), next(nullptr) {}
Node(int x) : val(x), next(nullptr) {}
*/
Node(){
val = 0;
next = nullptr;
}
Node(int val){
this->val = val;
next = nullptr;
}
};
class MyLinkedList {
private:
Node *head;
int len;
public:
MyLinkedList() {
this->head = new Node;
this->len = 0;
}
int get(int index) {
if(index < 0 || index >= this->len){
return -1;
}
Node *p = this->head->next;
for(int i=0; i<index; i++){
p = p->next;
}
return p->val;
}
void addAtHead(int val) {
Node *p = new Node(val);
p->next = this->head->next;
this->head->next = p;
len++;
}
void addAtTail(int val) {
Node *p = new Node(val);
Node *tail = this->head;
while(tail->next){
tail = tail->next;
}
tail->next = p;
len++;
}
void addAtIndex(int index, int val) {
if(index<0 || index > this->len) return;
Node *p = new Node(val);
Node *q = this->head;
for(int i=0; i<index; i++){
// q指向要插入位置的前一个结点
q = q->next;
}
p->next = q->next;
q->next = p;
len++;
}
void deleteAtIndex(int index) {
if(index < 0 || index >= this->len){
return;
}
Node *p = this->head;
for(int i=0; i<index; i++){
// p指向被删除结点的前一个结点
p = p->next;
}
// 被删除结点
Node *tmp = p->next;
p->next = tmp->next;
delete tmp;
len--;
}
};
/**
* 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. 反转链表
创建一个虚拟头结点代表新链表(反转后的链表)。遍历原链表,将结点头插到新链表中。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
1
)
O(1)
O(1)
// c++
/**
* 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* dummyHead = new ListNode;
ListNode* p = head, *cur;
while(p){
cur = p;
p = p->next;
// 头插
cur->next = dummyHead->next;
dummyHead->next = cur;
}
return dummyHead->next;
}
};