1.Leetcode203移除链表元素
题目链接:力扣
题目大意:给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
分析:本题可按删除的元素是否是头节点分成两种情况。如果是头节点,可直接令head->next为新的头节点,并删除原始的head。如果不是,则需查找节点值为val的上一个节点,并将cur->next = cur->next->next;
代码:
/**
* 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 * node = head;
while(head != NULL && head->val == val)//删除节点是头部的情况
{
ListNode *n2 = head;
head = head->next;
delete n2;
}
while(node != NULL && node->next != NULL)//其他情况
{
if(node->next->val == val)
{
ListNode *n2 = node->next;
node->next = n2->next;
delete n2;
}
else
{
node = node->next;
}
}
return head;
}
};
2.707设计链表
题目大意:
写一个链表并在链表类中实现这些功能:
get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
deleteAtIndex(index):如果索引 index 有效,则删除第 index 个节点。
分析:首先我们需要构造一个listnode的结构体,用来表示节点值val和next节点。
由于我们需要写addAtTaila函数,为了方便我们可以引入一个虚拟头部节点。其余思路与第一题相似。
代码:
class MyLinkedList {
public:
struct ListNode
{
int val;
ListNode * next;
ListNode(int x) : val(x),next(nullptr){};
};
int size1;
ListNode* dummyhead;//虚拟头节点
MyLinkedList() {
dummyhead = new ListNode(0);
size1 = 0;
}
int get(int index) {
if (index > (size1 - 1) || index < 0) {
return -1;
}
ListNode *cur = dummyhead->next;//真实的头节点是虚拟头节点的下一个节点
while(index--)
{
cur = cur->next;
}
return cur->val;
}
void addAtHead(int val) {
ListNode * newNode = new ListNode(val);
newNode->next = dummyhead->next;
dummyhead->next = newNode;
size1++;
}
void addAtTail(int val)
{ ListNode *newNode = new ListNode(val);
ListNode *cur = dummyhead;
while(cur->next != NULL)
cur = cur->next;
cur->next = newNode;
size1++;
}
void addAtIndex(int index, int val) {
ListNode *cur = dummyhead;//为了找到index-1的节点
if(index > size1) return;
if(index < 0) index = 0;
ListNode *newNode = new ListNode(val);
while(index--)
{
cur = cur->next;
}
newNode->next = cur->next;
cur->next = newNode;
size1++;
}
void deleteAtIndex(int index) {
if (index >= size1 || index < 0) {
return;
}
ListNode *cur = dummyhead;
while(index--)
{
cur = cur->next;
}
ListNode *tmp = cur->next;
cur->next = tmp->next;
delete tmp;
size1--;
}
void printLinkedList() {
ListNode* cur = dummyhead;
while (cur->next != nullptr) {
cout << cur->next->val << " ";
cur = cur->next;
}
cout << endl;
}
};
3.反转链表
题目大意:给你单链表的头节点 head
,请你反转链表,并返回反转后的链表
递归法:反转链表意味着原来cur要变成cur->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);
}
};
双指针法:此题也可用双指针来解决,用pre指针表示前一个节点,cur指针表示当前节点。
原理:
代码:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* tmp;
ListNode* cur = head;
ListNode* pre = NULL;
while(cur)
{
temp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
};