代码随想录算法训练营第三天 | 203.移除链表元素、707.设计链表、206.反转链表

题目:203.移除链表

文章链接:代码随想录

视频链接:LeetCode: 203.移除链表元素

题目链接:力扣题目链接

解法1:删除头节点

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        // 判断前面是不是有目标值
        while(head != NULL && head->val == val)
        {   
            head = head->next;  
        }
         if(head == NULL){
           return head;
        }
        // 如果链表开头有一串目标值的节点作为前缀的话,就可以直接将head跳过这些节点来删除,
        //这是这个while的作用,如果说整个链表的节点都是目标值,那head==null就直接通过if返回了。
        //如果交换顺序,在整个链表的节点都是目标值情况下,经过while循环,head会为null,
        //但是没法通过if退出,然后后面又访问了head.next,就发生空指针引用了
        // 删除非头节点
        ListNode* pre = head;
        ListNode* cur = head->next ;
        while(cur!= NULL)  // 当前指针不为空,以及下一个指针也不为空则循环
        {
            if(cur->val == val)
            {   
                pre->next = cur->next;
            }
            else{
                pre = cur ;
            }
            cur = cur->next; 
            
        }
        return head;
    }
};

解法2:创建虚拟头节点

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        // 创建虚拟头节点
       ListNode *demmpHead = new ListNode(0);  // 创建新的列表头
       demmpHead->next = head; //将虚拟头指向head
       ListNode *cur = demmpHead;
       while(cur->next != NULL )  // cur可以为NULL,当cur为NULL时,cur->next也为NULL
       {
           if(cur->next->val == val ) 
           {
               ListNode *temp = cur->next;
               cur->next = cur->next->next;
               delete temp;  // 释放内存

           }
           else{
               cur = cur->next;  // 往下走
           }
       }
       head = demmpHead->next;
       delete demmpHead;
       return head;
       }
    }
};

题目:707.设计链表

文章链接:代码随想录

视频链接:LeetCode: 707.设计链表

题目链接:力扣题目链接

解法1:

// 定义一个类
class MyLinkedList {
public:
	// 定义链表节点结构体
	struct LinkedList {
		int val;
		LinkedList* next;
		LinkedList(int val) :val(val), next(nullptr) {}
	};
private:
		int _size; // 在addAtHead中会进行size++的操作,所以定义一个全局数值
		LinkedList* _dummyHead;
public:        
	// 初始话链表  无参构造函数
	MyLinkedList() {
		_dummyHead = new LinkedList(0);  // 在前面加_  是为了区别类内全局值
		_size = 0;
	}

	int get(int index) {
		if (index < 0 || index >= _size)  // 小于0肯定是不对的,eg size = 0,里面没有数,index=0表示访问第一个数,但里面是没数的,所以返回-1
			return -1;
		LinkedList* cur = _dummyHead->next;
		while (index--)  // 0 是可以进while里的
		{
			cur = cur->next;  //循环下一个元素
		}
		return cur->val;
	}
	// 在链表最前面插入一个节点,插入完成后,新插入的节点为链表的新的头结点
	void addAtHead(int val) {
		LinkedList* newnode = new LinkedList(val);
		// 更换循序很关键
		newnode->next = _dummyHead->next;
		_dummyHead->next = newnode;
		_size++;

	}

	void addAtTail(int val) {
		LinkedList* newnode = new LinkedList(val);
		LinkedList* cur = _dummyHead;
		// 循环到链表尾
		while (cur->next != NULL)
		{
			cur = cur->next;
		}
		cur->next = newnode;  // 把原先的末尾节点赋值给新的节点
		_size++;  // 计数增加
	}

	void addAtIndex(int index, int val) {
		// 根据添加的位置分类讨论
		if (index>_size || index < 0){
			return;
		}
		else if (index==_size) {  //在末尾进行添加
			addAtTail(val);
			return;
		}
		else if (index==0){  //在头部添加
			addAtHead(val);
			return;
		}
		LinkedList* newnode =new LinkedList(val); //新建一个节点
		LinkedList* cur = _dummyHead;
		while (index--)  // 定位到插入的前一位
		{
			cur = cur->next;
		}
		newnode->next = cur->next;
		cur->next = newnode;
		_size++;
	}

	void deleteAtIndex(int index) {
		// 首先还是判断index还不是合规
		if (index < 0 || index >= _size)
			return ;
		LinkedList* cur = _dummyHead;   
		while (index--)  // 定位到插入的前一位  实在理不顺就换一个自己懂的
		{
			cur = cur->next;
		}
		LinkedList* temp = cur->next;
		cur->next = temp->next;
		delete temp;
        //delete命令指示释放了tmp指针原本所指的那部分内存,
        //被delete后的指针tmp的值(地址)并非就是NULL,而是随机值。也就是被delete后,
        //如果不再加上一句tmp=nullptr,tmp会成为乱指的野指针
        //如果之后的程序不小心使用了tmp,会指向难以预想的内存空间
        temp = NULL;
		_size--;
	}
};

 题目:206.反转指针

文章链接:代码随想录

视频链接:LeetCode: 206.反转链表

题目链接:力扣题目链接

解法1:

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
       ListNode* temp;
       ListNode* cur = head;  
       ListNode* pre = NULL; //作为尾部进行连接
       while(cur) // 当cur为空指针的时候,循环结束
       {
           // 暂存
           temp = cur->next;
           // 翻转  顺序不能相反
           cur->next = pre;
           // 更新
           pre = cur ; 
           cur = temp;
       }
       return pre;  // 当cur为空指针的时候,pre就是head了
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值