203.移除链表元素
- 题目链接:203.移除链表元素
- 独立思路:添加一个dummyhead,就不用讨论第一个结点元素值就为val的情况。p指针从dummy开始遍历全部链表,检查p->next->val值是否等于val
- 时间复杂度:O(n)
- 空间复杂度:O(1)
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummy = new ListNode(-1);
dummy->next = head;
ListNode* p = dummy;
while(p->next != NULL){
if(p->next->val == val)
p->next = p->next->next;
else
p = p->next;
}
return dummy->next;
}
};
- 另解(递归):对于传进去的head结点,若符合条件,则返回head->next,若不符合则直接返回head。
(递归思路很难想得到,但是一看代码又很简单,咋整)
- 时间复杂度:O(n)
- 空间复杂度:O(n)
//解法2: 递归
class Solution{
public:
ListNode* removeElements(ListNode* head, int val){
if(!head)
return NULL;
head->next = removeElements(head->next, val);
return head->val==val?head->next:head;
}
};
206.反转链表
- 题目链接:206.反转链表
- 独立思路:添加dummyhead,dummy->next先置为空,从head开始,将每个结点进行头插法,插入到dummy的后面,最后返回dummy->next即可
- 时间复杂度:O(n)
- 空间复杂度:O(1)
class Solution{
public:
ListNode* reverseList(ListNode* head){
ListNode* dummy = new ListNode(-1, NULL);
ListNode* p = head;
ListNode* q;
while(p){
q = p->next;
p->next = dummy->next;
dummy->next = p;
p = q;
}
return dummy->next;
}
};
- 另解(递归):假设head结点后面的结点全部已经完成逆转,则还需要做的工作就是把head结点放到已完成逆转的链表尾部,并且把head->next置空。(难想啊!)
- 时间复杂度:O(n)
- 空间复杂度:O(n)
class Solution{
public:
ListNode* reverseList(ListNode* head){
if(!head || !head->next)
return head;
ListNode* newHead = reverseList(head->next); //head->next及之后都已经逆转,且head->next位于逆转链表的尾部
head->next->next = head; //把head放到已逆转链表的尾部
head->next = NULL; //head已经放到尾部后,出现循环,所以要把head->next置空
return newHead;
}
};
707.设计链表
- 题目链接:707.设计链表
- 独立思路:❌ 没设计过,不知道怎么下手
- 问题(已解决但还要多练多想):第一次提交时,只判断了index的合法性,其他的的特殊情况都被忽略,如index=0时,head本来就为空(size为0/head为NULL)时。
- 时间复杂度:O(n)
- 空间复杂度:O(1)
class MyLinkedList {
private:
ListNode* head;
int size;
public:
MyLinkedList(): head(NULL), size(0) {} //构造函数,直接初始化
int get(int index) { //获取第index个结点的元素值
if(index < 0 || index >= size)
return -1;
int cnt = 0; //index从0开始,head下标为0
ListNode* p = head;
while(cnt != index){
p = p->next;
cnt++;
}
return p->val;
}
void addAtHead(int val) { //头插法,插入值为val的结点
ListNode* newNode = new ListNode(val);
newNode->next = head;
head = newNode;
size++;
}
void addAtTail(int val) { 尾插法,插入值为val的结点
ListNode* newNode = new ListNode(val);
if (size == 0){
head = newNode;
size++;
return;
}
ListNode* tail = head;
int cnt = 1; //1~size共size个
while(cnt != size){ //让tail指向尾结点
tail = tail->next;
cnt++;
}
tail->next = newNode;
size++;
}
void addAtIndex(int index, int val) { //插入一个新结点到下标为index的结点之前
if(index < 0 || index > size)
return;
ListNode* newNode = new ListNode(val);
if(index == 0){
newNode->next = head;
head = newNode;
size++;
return;
}
ListNode* p = head;
int cnt = 0;
while(cnt != index-1) { //让p最终指向index的前一个结点
p = p->next;
cnt++;
}
newNode->next = p->next;
p->next = newNode;
size++;
}
void deleteAtIndex(int index) {
if(index < 0 || index >= size)
return;
if (index == 0){
ListNode* temp = head;
head = head->next;
delete temp;
size--;
return;
}
ListNode* p = head;
int cnt = 0;
while(cnt != index-1) { //让p最终指向index的前一个结点
p = p->next;
cnt++;
}
ListNode* del = p->next;
p->next = del->next;
delete del;
size--;
}
};