目录
leetcode203.移除链表元素
题目链接 :203.移除链表元素
思路
1.在原链表上移除元素:
若移除结点为头节点,则将头节点向后移一位。
若移除结点不为头节点,则让指向该B节点的A节点 指向B节点指向的C节点,来实现对B节点的移除。
2.设置一个虚拟头节点:
这样一来,对于所有节点都可以使用统一的处理方式,
代码
//在原链表上移除元素
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
while(head != NULL && head->val == val){
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;
}
};
//设置一个虚拟头节点
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyHead = new ListNode(0);//设置一个虚拟头节点
dummyHead->next = head;//让虚拟节点指向头节点,方便后面做删除操作
ListNode* cur = dummyHead;
while(cur->next != NULL){
if(cur->next->val == val){
ListNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
}
else{
cur = cur->next;
}
}
head = dummyHead->next;
delete dummyHead;
return head;
}
};
复杂度
时间复杂度:O(n)
空间复杂度: O(1)
leetcode707.设计链表
题目链接:707.设计链表
思路:
get(index)通过while循环遍历,将current指针指向第index个节点,输出cur->val
addAtHead(val)通过先将newNode指向 dummyHead->next ,再将dummyHead指向newNode即可实现插入一个新的头节点newNode
addAtTail(val)先通过循环遍历将current移动到链表尾,再将current指向newNode即可实现在链表最后面添加一个节点
addAtIndex(index,val)先初始化一个newNode节点,通过循环遍历将current移动到第(index-1)个节点,通过将newNode节点指向第(index-1)->next,再将第(index-1)个节点指向newNode即可实现在第index个节点前面插入一个新节点
deleteAtIndex(index)通过循环将current移动到第(index-1)个节点,这样一来,current->next即为我们想要删除的节点。通过构造一个tmp节点指向current->next,再将current->next指向current->next->next.最后把tmp delete掉即可
代码
class MyLinkedList {
public:
//定义链表节点结构体
struct LinkedNode{
int val;
LinkedNode* next;
LinkedNode(int val):val(val),next(nullptr){}
};
//初始化链表
MyLinkedList() {
dummyHead = new LinkedNode(0);
size = 0;
}
//获取到第index个节点的数值,需注意index是从0开始的,第0个节点就是头节点
int get(int index) {
if(index > (size - 1) || index <0){
return -1;
}
LinkedNode* cur = dummyHead->next;
while(index--){
cur = cur->next;
}
return cur->val;
}
//在链表最前面插入一个节点,插入完成后,新插入的节点为链表的新的头节点
void addAtHead(int val) {
LinkedNode* newNode = new LinkedNode(val);
newNode->next = dummyHead->next;
dummyHead->next = newNode;
size++;
}
//在链表的最后面添加一个节点
void addAtTail(int val) {
LinkedNode* newNode = new LinkedNode(val);
LinkedNode* cur = dummyHead;
while(cur->next!= nullptr){
cur = cur->next;
}
cur->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;
LinkedNode* newNode = new LinkedNode(val);
LinkedNode* cur = dummyHead;
while(index--){
cur = cur->next;
}
newNode->next = cur->next;
cur->next = newNode;
size++;
}
//删除第index个节点,如果index大于等于链表的长度,直接return,需注意index是从0开始的
void deleteAtIndex(int index) {
if(index >= size ||index < 0){
return;
}
LinkedNode* cur = dummyHead;
while(index--){
cur = cur->next;
}
LinkedNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
tmp = nullptr;
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);
*/
leetcode206.反转链表
题目链接: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;
ListNode* cur = head;
ListNode* pre = NULL;
while(cur){
tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
};
//递归法
/**
* 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* pre, ListNode* cur){
if(cur == NULL) return pre;
ListNode* tmp = cur->next;
cur->next = pre;
return reverse(cur, tmp);
}
ListNode* reverseList(ListNode* head) {
return reverse(NULL,head);
}
};
复杂度
时间复杂度:O(n), 对每一个节点都进行了一次反转处理。
空间内复杂度: O(n),递归调用了n层栈空间。