Leetcode 203 删除链表节点
感觉使用虚拟头节点方便理解,如果不使用虚拟头节点需要单独写一段处理头节点的代码
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点
dummyHead->next = head; // 将虚拟头结点指向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;
}
};
Leetcode 707设计链表
class MyLinkedList {
public:
struct LinkNode
{
LinkNode*prev;
LinkNode*next;
int val_;
LinkNode(int val):val_(val),prev(nullptr),next(nullptr){};
};
MyLinkedList() {
dummyHead=new LinkNode(0);
dummyTail=new LinkNode(0);
size_=0;
dummyHead->next=dummyTail;
dummyTail->prev=dummyHead;
}
int get(int index) {
if(index>=size_||index<0)
return -1;
int num;
LinkNode*cur=dummyHead;
for(int i=0;i<index;++i)
{
cur=cur->next;
}
num=cur->next->val_;
delete cur;
return num;
}
void addAtHead(int val) {
LinkNode*newNode=new LinkNode(val);
LinkNode*temp=new LinkNode(0);
temp->next=dummyHead->next;
dummyHead->next=newNode;
newNode->prev=dummyHead;
newNode->next=temp->next;
temp->next->prev=newNode;
size_++;
delete temp;
}
void addAtTail(int val) {
LinkNode*newNode=new LinkNode(val);
LinkNode*temp=new LinkNode(0);
temp->prev=dummyTail->prev;
dummyTail->prev=newNode;
newNode->next=dummyTail;
newNode->prev=temp->prev;
temp->prev->next=newNode;
size_++;
delete temp;
}
void addAtIndex(int index, int val) {
if(index==0)
{
addAtHead(val);
return ;
}
if(index==size_)
{
addAtTail(val);
return;
}
if(index>size_)
{
return;
}
LinkNode*cur=dummyHead;
LinkNode*newNode=new LinkNode(val);
LinkNode*temp=new LinkNode(0);
for(int i=0;i<index;i++)
{
cur=cur->next;
}
temp->next=cur->next;
cur->next=newNode;
newNode->prev=cur;
newNode->next=temp->next;
temp->next->prev=newNode;
size_++;
delete temp;
}
void deleteAtIndex(int index) {
if(index>=size_||index<0)
return;
LinkNode*cur=dummyHead;
LinkNode*temp=new LinkNode(0);
for(int i=0;i<index;i++)
{
cur=cur->next;
}
temp->next=cur->next->next;
cur->next=cur->next->next;
temp->next->prev=cur;
size_-=1;
delete temp->next;
delete temp;
}
private:
LinkNode*dummyHead;
LinkNode*dummyTail;
int size_;
};
/**
* 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);
*/
如上面所示代码,有问题,但是看不出来哪有问题。随后按照代码随想录的思路进行编写,其中最需要注意的位置是get、addAtIndex、deleteAtIndex中的循环条件,其中get需要cur正好位于index,而add、delete需要cur位于index位置的前一个或者后一个,这道题需要多练几遍。
class MyLinkedList {
public:
struct LinkNode
{
LinkNode* prev;
LinkNode* next;
int val_;
LinkNode(int val) :val_(val), prev(nullptr), next(nullptr) {};
};
MyLinkedList() {
sentinelNode = new LinkNode(0);
size_ = 0;
sentinelNode->next = sentinelNode;
sentinelNode->prev = sentinelNode;
}
int get(int index) {
if (index >= size_ || index < 0)
return -1;
int num;
LinkNode* cur = sentinelNode;
int mid = size_ >> 1;
if (index < mid)
{
for (int i = 0; i < index -1; i++)
{
cur = cur->next;
}
}
else {
for (int i = 0; i < size_ - index; i++)
{
cur = cur->prev;
}
}
num = cur->val_;
return num;
}
void addAtHead(int val) {
LinkNode* newNode = new LinkNode(val);
LinkNode* temp = sentinelNode->next;
newNode->prev = sentinelNode;
newNode->next = sentinelNode->next;
sentinelNode->next = newNode;
temp->prev = newNode;
size_++;
}
void addAtTail(int val) {
LinkNode* newNode = new LinkNode(val);
LinkNode* temp;
temp = sentinelNode->prev;
newNode->next = sentinelNode;
newNode->prev = temp;
sentinelNode->prev = newNode;
temp->next = newNode;
size_++;
}
void addAtIndex(int index, int val) {
if (index == 0)
{
addAtHead(val);
return;
}
if (index > size_)
{
return;
}
int mid = size_ >> 1;
LinkNode* cur = sentinelNode;
LinkNode* newNode = new LinkNode(val);
if (index < mid)
{
for (int i = 0; i < index; i++)
{
cur = cur->next;
}
LinkNode* temp = cur->next;
cur->next = newNode;
temp->prev = newNode;
newNode->next = temp;
newNode->prev = cur;
size_++;
}
else
{
for (int i = 0; i < size_ - index ; ++i)
{
cur = cur->prev;
}
LinkNode* temp = cur->prev;
cur->prev = newNode;
temp->next = newNode;
newNode->prev = temp;
newNode->next = cur;
size_++;
}
}
void deleteAtIndex(int index) {
if (index >= size_ || index < 0)
return;
int mid = size_ >> 1;
LinkNode* cur = sentinelNode;
if (index < mid)
{
for (int i = 0; i < index; ++i)
{
cur = cur->next;
}
LinkNode* temp = cur->next->next;
cur->next = temp;
temp->prev = cur;
size_--;
}
else {
for (int i = 0; i < size_ - index - 1; ++i)
{
cur = cur->prev;
}
LinkNode* temp = cur->prev->prev;
cur->prev = temp;
temp->next = cur;
size_--;
}
}
private:
LinkNode* sentinelNode;
int size_;
};
Leetcode 206
单向链表反转,之前没接触过,应该说单向链表都没怎么接触过,对于我眼前一亮的地方在于
ListNode*pre=nullptr;
这样cur->next直接=pre即可把尾节点next赋值为nullptr
判断条件为cur,当cur为nullptr时pre正好成为新的head
通过画图可以很好理解
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode*cur=head;
ListNode*prev=nullptr;
while(cur)
{
ListNode*temp=cur->next;
cur->next=prev;
prev=cur;
cur=temp;
}
return prev;
}
};
很少写链表,更别说设计链表了,画图画了半天有点懵,中间边界条件判断很难看出来错误,还是需要多写,下周需要复习这一部分内容,通过画图能够更加直观了解问题。
浙公网安备 33010602011771号