写在前面
不贪,勿嗔,莫痴
203.答题过程
直接使用原来的链表来进行移除节点操作:
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
//当需要删除的是头结点
while(head!=nullptr&&head->val==val){//这里head可以直接拿来用,不用再了,这里后面的保证头结点不是空
ListNode* tmp=head;//C++中移除结点需要手动删去占用空间
head=head->next;//注意=左右的位置
delete tmp;//删除空间
}
//当删除的是非头结点
ListNode* cur=head;//创建一个结点 用来做删除操作
while(cur!=nullptr&&cur->next!=nullptr){//第一个判断保证头结点不是空的
if(cur->next->val==val){
ListNode* tmp=cur->next;
cur->next=cur->next->next;
delete tmp;
}
else cur=cur->next;//cur往后移一位,好进入下一个while进行处理
}
return head;//返回新的头结点,输出是一串链表
}
};
在头结点前构建一个虚拟的结点用来进行移除结点操作:
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
//构建一个虚拟结点在head前面
ListNode* dummyHead=new ListNode(0);//创建一个虚拟结点
dummyHead->next=head;//让虚拟结点的next指向head 方便后面的删除操作
ListNode* cur=dummyHead;
while(cur->next!=nullptr){//这里建立了一个虚拟头结点,所以头结点肯定不是空
if(cur->next->val==val){
ListNode* tmp=cur->next;
cur->next=cur->next->next;
delete tmp;
}
else cur=cur->next;
}
head=dummyHead->next;//注意这里的head=的是dummyHead->next而不是dummyHead
delete dummyHead;//删除一开始创建的虚拟结点
return head;
}
};
707.答题过程
class MyLinkedList {
public://注意 说从第n个结点怎么样,头结点是从0开始的
//定义链表节点结构体
struct LinkedNode{
int val;
LinkedNode* next;
LinkedNode(int val):val(val),next(nullptr){}
};
//初始化链表
MyLinkedList() {
dummyHead=new LinkedNode(0);// 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
size=0;
}
// 获取到第index个节点数值,如果index是非法数值直接返回-1, 注意index是从0开始的,第0个节点就是头结点
int get(int index) {
if(index>(size-1)||index<0){
return -1;
}
LinkedNode* cur=dummyHead->next;//创建临时结点=头结点
while(index--){//是第index结点,那么就直接让用cur移index位,如果是--index话会进入循环
cur=cur->next;//cur移动到下一位
}
return cur->val;
}
//在链表最前面插入一个节点,插入完成后,新插入的结点为链表的新头结点
void addAtHead(int val) {
LinkedNode* newNode=new LinkedNode(val);
newNode->next=dummyHead->next;//插入新结点的方法
dummyHead->next=newNode;
size++;//size需要变化
}
//在链表最后面添加一个节点
void addAtTail(int val) {
LinkedNode* newNode=new LinkedNode(val);
LinkedNode* cur=dummyHead;//创建一个临时cur以便找到最后一个节点
while(cur->next!=nullptr){//如果cur的下一个节点不是nullper,那么就让cur往前走一位
cur=cur->next;
}
cur->next=newNode;//在链表最后添加节点
size++;
}
// 在第index个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
// 如果index 等于链表的长度,则说明是新插入的节点为链表的尾结点
// 如果index大于链表的长度,则返回空
// 如果index小于0,则置为0,作为链表的新头节点。
void addAtIndex(int index, int val) {
if (index > size || index < 0) {//index大于链表长度返回空,因为创建了虚拟头结点,所以不用再做其他,直接return 注意这里的index小于0做测试案例其实是不行的。
return ;
}
LinkedNode* newNode = new LinkedNode(val);
LinkedNode* cur = dummyHead;//和上面有所不同的是这里cur=dummyHead不是dummyHead->next
while(index--) {//所以这里找到第index个结点前面的一个结点,所以这里是插入到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;//注意这里也是从dummyHead开始的
while(index--) {
cur = cur ->next;
}
LinkedNode* tmp = cur->next;//也就是说此时的cur是index前一个结点
cur->next = cur->next->next;
delete tmp;
size--;
}
// 打印链表 这部分不写在LeetCode也可以运行
void printLinkedList() {
LinkedNode* cur = dummyHead;
while (cur->next != nullptr) {
cout << cur->next->val << " ";
cur = cur->next;
}
cout << endl;
}
private://这里需要自己定义一下
int size;
LinkedNode* dummyHead;
}
206.答题过程
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* cur=head;
ListNode* pre=nullptr;
ListNode* tmp;//先把下一个cur存储起来 注意这里要放在while外面 因为tmp每个循环都需要
while(cur){//这里的意思是cur不等于nullptr时候都循环
tmp=cur->next;
cur->next=pre;//优先得吧方向反转了
pre=cur;
cur=tmp;
//delete tmp;//不能delete 删除,因为之后的循环还需要用
}
return pre;//返回的是头结点,最终cur是null,pre是正向最后一个节点,也就是翻转后的头结点
}
}