链表的定义
struct ListNode {
int val; // 节点上存储的元素
ListNode *next; // 指向下一个节点的指针
ListNode(int x) : val(x), next(NULL) {} // 节点的构造函数
};
203.移动链表元素
题目链接https://leetcode.cn/problems/remove-linked-list-elements/description/
天哪,以前学C语言链表要难死我了,这么看也不是特别难理解..
用普通方法需要考虑是头结点和不是头结点的情况,用虚拟头结点就不用考虑这个问题,嘿嘿,那当然选虚拟头结点啦
用虚拟指针进行删除的时候,如果用的c++书写代码,注意要事先把要删的地址保存出来,因为在把上一个指针指向下一个指针之后,这个要删的指针就已经访问不到了,所以删的时候直接删保存的temp的地址就行
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyNode=new ListNode();
dummyNode->next=head;
ListNode* cur=dummyNode;
while(cur->next!=NULL){
if(cur->next->val==val){
ListNode* temp=cur->next;
cur->next=cur->next->next;上一个指针指向下一个指针
delete temp;
}
else{
cur=cur->next;//指向下一个指针
}
}
return dummyNode->next;//不能return head,因为head在中间有可能已经删除了
//要指向新的链表的head就只能用dummyNode->next
}
};
707.设计链表
题目链接. - 力扣(LeetCode)
首先自己要先定义链表,把结构体里面结点上存储的元素,指向下一个结点的指针,结点的构造函数先定义好
在初始化链表的时候可以加上进行定义头结点和机上计数的size.
最开始一直不明白为什么要把size不能在链表内部定义,后来想想我要size只是想知道现在有几个结点了,如果把它定义在链表内部,我到时候还得再去找指向最后那个链表的size现在是几了,那不如我直接定义成类的成员啊,我添加链表删除链表的时候直接调用改变size,多爽。
这道题跟上一道不完全相等LinkeNode* dummyhead;最开始我定义在了 MyLinkedList()里面,这样的话在其他函数需要使用dummyhead的时候就会报错,所以可以在私有段声明一下dummyhead然后在MyLinkedList里面赋值。
class MyLinkedList {
public:
struct LinkeNode{
int val;
LinkeNode *next;
LinkeNode(int val):val(val),next(NULL){}
};
MyLinkedList() {
dummyhead=new LinkeNode(0);
}
int get(int index) {
LinkeNode* cur=dummyhead->next;//cur指向的就是下标为0的链表了
if(index<0||index>size-1){
return -1;
}
while(index--){
cur=cur->next;
}
return cur->val;
}
void addAtHead(int val) {
LinkeNode* newnode=new LinkeNode(val);
newnode->next=dummyhead->next;//先把newnode指向下一个指针,再把dummyhead指向newnode
dummyhead->next=newnode;
size++;
}
void addAtTail(int val) {
LinkeNode* cur=dummyhead;
LinkeNode* newnode=new LinkeNode(val);
while(cur->next!=NULL){
cur=cur->next;
}
cur->next=newnode;
size++;
}
void addAtIndex(int index, int val) {
LinkeNode* cur=dummyhead;
if(index>size){return;}
LinkeNode* newnode=new LinkeNode(val);
while(index--){
cur=cur->next;
}
newnode->next=cur->next;
cur->next=newnode;
size++;
}
void deleteAtIndex(int index) {
LinkeNode* cur=dummyhead;
while(index--){
cur=cur->next;
}
LinkeNode* tmp=new LinkeNode(0);
tmp=cur->next;
cur->next=cur->next->next;
delete tmp;
size--;
}
void printLinkedList() {
LinkeNode* cur = dummyhead;
while (cur->next != NULL) {
cout << cur->next->val << " ";
cur = cur->next;
}
cout << endl;
}
private:
int size=0;
LinkeNode* 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);
*/
206.反转链表
题目链接https://leetcode.cn/problems/reverse-linked-list/
/**
* 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* pre=NULL;
ListNode* cur=head;
while(cur){
ListNode*temp;
temp=cur->next;//要先把后一个进行保存,否在在反向后找不到下一个值了
cur->next=pre;//要把cur指向指向前一个进行翻转
pre=cur;
cur=temp;
}
return pre;
}
};