DAY03 | 203.移除链表元素、707.设计链表、206.反转链表

203.移除链表元素

移除元素时需要考虑移除的是头结点非头结点两种情况,如果使用虚拟头结点dummy就可以解决分类讨论的问题

typedef ListNode* node;
class Solution {
public:
	ListNode* removeElements(ListNode* head, int val) {
		ListNode*dummy = new ListNode();
		dummy->next = head;
		node pre = dummy;
		//要删除一个结点需要找到它的前驱结点才能删除
		node p = head;
		node tmp = nullptr;
		while (p!=nullptr)
		{
			if (p->val == val) {
			//找到需要删除的结点后释放其内存
				pre->next = p->next;
				tmp = p;
				delete tmp;
				tmp = nullptr;
				p = pre->next;
			}
			else {
			//没找到就继续遍历链表
				p = p->next;
				pre = pre->next;
			}
		}
		return dummy->next;
	}
};

707.设计链表

	struct LinkedNode
	{
		int val;
		LinkedNode*next;
		LinkedNode(int val):val(val),next(nullptr){}
	};
	MyLinkedList() {
		dummy = new LinkedNode(0);
		size = 0;
	}

链表初始化时仅有一个dummy结点

	int get(int index) {
		if (index<0 || index>size - 1)return -1;
		LinkedNode*cur = dummy->next;
		while (index--)
		{
			cur = cur->next;
		}
		return cur->val;
	}

由于链表头结点序号为0,所以在寻找该结点的过程中cur应该赋值为dummy->next也就是真正的头结点
边界条件不确定时可以用极端情况检验,例如当index=0时,while循环此时不执行,返回的就是头结点的值

	void addAtHead(int val) {
		LinkedNode*head = new LinkedNode(val);
		head->next = dummy->next;
		dummy->next = head;
		size++;
	}

	void addAtTail(int val) {
		LinkedNode*p = dummy;
		while (p->next!=nullptr)
		{
			p = p->next;
		}
		LinkedNode*tail = new LinkedNode(val);
		p->next = tail;
		size++;
	}

注意在尾部插入结点时指针p=dummy这样赋值是为了避免在链表为空时访问nullptr
起初我赋值成p=dummy->next,但是当链表初始化后就插入结点的情况下就会出现访问nullptr的错误

	void addAtIndex(int index, int val) {
		if (index > size)return;
		if (index < 0)index = 0;
		else {
			LinkedNode*node = new LinkedNode(val);
			LinkedNode*cur = dummy->next;
			LinkedNode*pre = dummy;
			while (index--)
			{
				cur = cur->next;
				pre = pre->next;
			}
			node->next = cur;
			pre->next = node;
		}
		size++;

	}

	void deleteAtIndex(int index) {
		if (index<0 || index>size - 1)return;
		LinkedNode*cur = dummy->next;
		LinkedNode*pre = dummy;
		while (index--)
		{
			cur = cur->next;
			pre = pre->next;
		}
		pre->next = cur->next;
		delete cur;
		cur = nullptr;
		size--;

	}

在插入结点时,由于需要插入在目标结点之前,所以需要找到它的前驱结点,寻找目标结点的过程和get函数一样,找到后执行插入操作

206.反转链表

具体思路就是用双指针precur,把cur指向pre,但是这样做又会丢失cur->next所以需要用tmp来保存cur->next具体代码如下

class Solution {
public:
	ListNode* reverseList(ListNode* head) {
		if (head == nullptr||head->next==nullptr)return head;
		ListNode*tmp = nullptr;
		ListNode*pre = nullptr;
		ListNode*cur = head;
		while (cur!=nullptr)
		{
			tmp = cur->next;
			cur->next = pre;
			pre = cur;
			cur = tmp;
		}
		return pre;
	}
};
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值