Leetcode203
题目
![](https://img-blog.csdnimg.cn/30f3ac9634cf4da58f6f282cac0e560f.png)
本人解法(用了两个指针)
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode *p,*q;
while(head!=NULL&&head->val==val)
{
ListNode* tmp=head;
head=head->next;
delete tmp;
}
if(head==NULL)
{
return NULL;
}
p=head->next;
q=head;
while(p!=NULL&&q!=NULL)
{
if(p->val==val)
{
q->next=p->next;
ListNode* tmp=p;
p=q->next;
delete tmp;
}
else{
p=p->next;
q=q->next;
}
}
return head;
}
};
单指针解法:
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
// 删除头结点
while (head != NULL && head->val == val) { // 注意这里不是if
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; // 将虚拟头结点指向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;
}
};
感悟:
- 这里主要是一个带头结点的链表和不带头结点的链表的一个删除操作,引入虚拟节点也是人为制造一个头结点,就不用单独在处理头结点的情况
- 编译器的要求比较严格,只要存在访问越界的情况都会报错
- 不释放头结点空间也可以过
Leetcode707
题目:
![](https://img-blog.csdnimg.cn/8064a7a3c5f34dad9d413c0f60ad7441.png)
自己瞎写的无法运行版本:
class MyLinkedList {
public:
int val;
MyLinkedList *next;
MyLinkedList() {
MyLinkedList *head;
head=(MyLinkedList*)malloc(sizeof(MyLinkedList));
head->next=NULL;
}
int get(int index) {
int i=0;
MyLinkedList *tmp=head;
for(i=0;i<index;i++)
{
if(tmp==NULL)
return -1;
tmp=tmp->next;
}
return tmp->val;
}
void addAtHead(int val) {
MyLinkedList *tmp;
tmp->val=val;
tmp->next=head;
head=tmp;
}
void addAtTail(int val) {
MyLinkedList *tmp=head;
while(tmp->next!=NULL)
{
tmp=tmp->next;
}
MyLinkedList *tail;
tail->val=val;
tmp->next=tail;
tail->next=NULL;
}
void addAtIndex(int index, int val) {
MyLinkedList *tmp=head;
int i;
for(i=1;i<index;i++)
{
if(tmp->next==NULL)
{
return;
}
tmp=tmp->next;
}
MyLinkedList *Index;
Index->val=val;
Index->next=tail->next;
tail->next=Index;
}
void deleteAtIndex(int index) {
MyLinkedList *tmp=head;
MyLinkedList *de;
int i;
for(i=1;i<index;i++)
{
if(tmp->next==NULL)
{
return;
}
tmp=tmp->next;
}
if(tmp->next!=NULL)
{
de=tmp->next;
tmp->next=tmp->next->next;
delete(de);
}
}
};
答案版本:
class MyLinkedList {
public:
struct LinkedNode{
int val;
LinkedNode* next;
LinkedNode(int val):val(val),next(nullptr){}
};
MyLinkedList() {
_dummyHead=new LinkedNode(0);
_size=0;
}
int get(int index) {
if (index < 0 || index >= _size) {
return -1;
}
LinkedNode *cur = _dummyHead->next;
for (int i = 0; i < index; i++) {
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* Newtail = new LinkedNode(val);
LinkedNode* tmp=_dummyHead;
for(int i=0;i<_size;i++)
{
tmp=tmp->next;
}
tmp->next=Newtail;
Newtail->next=NULL;
_size++;
}
void addAtIndex(int index, int val) {
if (index > _size) {
return;
}
LinkedNode* NewIndex = new LinkedNode(val);
LinkedNode* tmp=_dummyHead;
for(int i=0;i<index;i++)
{
tmp=tmp->next;
}
NewIndex->next=tmp->next;
tmp->next=NewIndex;
_size++;
}
void deleteAtIndex(int index) {
if (index < 0 || index >= _size) {
return;
}
_size--;
LinkedNode *pred = _dummyHead;
for (int i = 0; i <index; i++) {
pred = pred->next;
}
LinkedNode *p = pred->next;
pred->next = pred->next->next;
delete p;
}
void printLinkedList() {
LinkedNode* cur = _dummyHead;
while (cur->next != nullptr) {
cout << cur->next->val << " ";
cur = cur->next;
}
cout << endl;
}
private:
int _size;
LinkedNode* _dummyHead;
};
感悟 :
- 一个链表设计卡了我三天,虽然不是因为难度而是破事实在是太多了
- 后面要抓紧进度了
206反转链表
题目
![](https://img-blog.csdnimg.cn/4a5ee7c56e904f57b58caaef8a97cd64.png)
本人解法:(使用数组记录节点值,再将节点值反过来导入)
class Solution {
public:
ListNode* reverseList(ListNode* head) {
int A[5000];
int i=0;
if(head==NULL)
return head;
ListNode* cur = head;
while(cur->next!=NULL)
{
A[i++]=cur->val;
cur=cur->next;
}
A[i]=cur->val;
cur= head;
for(;i>=0;i--)
{
cur->val=A[i];
cur=cur->next;
}
return head;
}
};
双指针法
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* cur=head;
ListNode* pre=NULL;
ListNode* tmp;
while(cur)
{
tmp=cur->next;
cur->next=pre;
pre=cur;
cur=tmp;
}
return pre;
}
};
感悟:
- 用数组存储的方法算是一种钻空子的方法,在链表节点个数已知的情况下可以使用
- 双指针法比较经典,需要掌握