代码随想录day3|203.移除链表元素、707.设计链表 、 206.反转链表

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&&current->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&&current->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);
    }
};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值