203.移除链表元素
方法1:分开写删除头结点和中间节点
注意:用while循环,因为删除直到head或者中间值!=val。
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
//ListNode *current=head;
while(head!=NULL&&head->val==val){//头结点=val 用while不用if
head=head->next;
}
ListNode *current=head;
while(current!=NULL&¤t->next!=NULL){//如果是1 1 1 1 则一直删除值,用while不用if
if(current->next->val==val){//当前值的下一个值=val
current->next=current->next->next;
}
else
current=current->next;
}
return head;
}
};
方法2:虚拟头结点
把前面两种情况合并了
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* newhead=new ListNode(0);//定义新的虚拟头结点
newhead->next=head;
ListNode *current=newhead;
while(current!=NULL&¤t->next!=NULL){
if(current->next->val==val){//当前值的下一个值=val
current->next=current->next->next;
}
else
current=current->next;
}
return newhead->next;//注意返回虚拟头结点,因为之前的头结点可能被删除了
}
};
707.设计链表
熟悉链表的操作。
注意:在index处插入节点,index可以=size,代表在尾部前面插入节点,所以index>_size
删除节点,index>_size-1,因为超过_size-1就没有值了。
还要注意size长度变化。
class MyLinkedList {
public:
struct LinkedNode{//定义链表结构
int val; // 节点上存储的元素
LinkedNode *next; // 指向下一个节点的指针
LinkedNode(int x) : val(x), next(NULL) {}; // 节点的构造函数
};
MyLinkedList() {
newhead=new LinkedNode(0);//虚拟头结点,不加LinkedNode *,LinkedNode *是局部变量
_size=0;
}
//获取index结点值
int get(int index) {
if(index<0||index>(_size-1)){
return -1;
}
LinkedNode *cur=newhead;
while(index--){//cur到达index前一个值,使得cur->next为index
cur=cur->next;
}
return cur->next->val;
}
// 链表前插入结点
void addAtHead(int val) {
LinkedNode *newcode=new LinkedNode(val);//定义新节点
newcode->next=newhead->next;
newhead->next=newcode;
_size++;
}
// 在链表最后添加一个节点
void addAtTail(int val) {
LinkedNode *newcode=new LinkedNode(val);
LinkedNode *cur=newhead;
while(cur->next!=NULL){//cur指向最后一个节点
cur=cur->next;
}
cur->next=newcode;//最后一个结点后面默认指向NULL
_size++;
}
// 在下标为index个节点之前插入一个新节点
void addAtIndex(int index, int val) {
if(index>_size)return;//注意:可以=size,就是在尾部插入结点
if(index<0) index=0;
LinkedNode *newcode=new LinkedNode(val);
LinkedNode *cur=newhead;
while(index--){//cur指到index前一个结点
cur=cur->next;
}
newcode->next=cur->next;
cur->next=newcode;
_size++;
}
// 删除下biao为index的节点
void deleteAtIndex(int index) {
if(index>_size-1||index<0)return;//下标从0开始,超过_size-1就没有值
LinkedNode *cur=newhead;
while(index--){//cur指到index前一个结点
cur=cur->next;
}
cur->next=cur->next->next;
_size--;
}
// 打印链表
void printLinkedList() {
LinkedNode* cur = newhead;
while (cur->next != nullptr) {
cout << cur->next->val << " ";
cur = cur->next;
}
cout << endl;
}
private://声明
LinkedNode* newhead;
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);
*/
206、反转链表
方法1:双指针法,将正向指针反转
/**
* 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*cur=head;//listnode和linkednode都可以
ListNode*pre=NULL;
while(cur!=NULL){
ListNode*temp=cur->next;
cur->next=pre;//反转指针
pre=cur;
cur=temp;
}
return pre;
}
};
方法2:递归法(双指针的改写)
注意;return reverse
class Solution {
public:
ListNode* reverse(ListNode* cur,ListNode* pre) {
if(cur==NULL)return pre;//判决条件
ListNode*temp=cur->next;
cur->next=pre;
return reverse(temp,cur);//cur=temp,pre=cur,继续反转
}
ListNode* reverseList(ListNode* head) {
return reverse(head,NULL);
}
};