《程序员代码面试指南》it名企算法与数据结构题目最优解(第二版)刷题笔记7

本文详细介绍了如何使用C++实现链表的基本操作,包括删除中间节点、删除a/b位置的节点,以及反转单向和双向链表的方法。文章通过具体代码示例展示了这些操作的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于之前看了牛客网的数据结构和算法的课程知道了左神,现在找到了这本书当作入门书做做吧,虽然书的题解都是java实现的,但好在用c++实现难度不大。

第二章 链表问题

第一题:删除链表的中间节点和a/b处的节点
删除节点的题目我们之前已经讨论过,如果要删除一个节点,则需要找到待删除节点的前一个节点。
删除中间节点

struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};
ListNode* removeLastKthNode(ListNode *head, int n) {
	if (head == NULL || head->next == NULL)
	{
		return head;
	}
	if (head->next->next == NULL)
	{
		return head->next;
	}
	ListNode* pre = head;
	ListNode* cur = head->next->next;
	while (cur->next != NULL &&cur->next->next!=NULL) {
		pre = pre->next;
		cur = cur->next->next;
	}
	pre->next = pre->next->next;
	return head;
}

删除a/b处节点
首先算出链表的长度n,再通过向上取整求得double r=((double)(a*n))/((double)b)的值即为要删除的节点。

struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}

};
ListNode* removeLastKthNode(ListNode *head, int a,int b) {
	if (a<1 || a>b) {
		return head;
	}
	int n = 0;
	ListNode* count = head;
	while (count != NULL) {
		count = count->next;
		++n;
	}
	n = (int)ceil(((double)(a*n)) / ((double)b));
	if (n == 1) {
		return head->next;
	}
	if (n > 1) {
		count = head;
		while (n != 1) {
			count = count->next;
			--n;
		}
		count->next = count->next->next;
		return head;
	}
}

第二题:反转单向链表和双向链表
关键在while循环
反转单向链表

struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}

};
ListNode* removeLastKthNode(ListNode *head) {
	if (head == NULL || head->next == NULL)return head;
	ListNode* pre = NULL, *next = NULL;
	while (head != NULL) {
		next = head->next;
		head->next = pre;
		pre = head;
		head = next;
	}
	return pre;
}

反转双向链表
关键还是在while循环里加了一句head->last = next;

struct DoubleListNode {
	int val;
	DoubleListNode *last;
	DoubleListNode *next;
	DoubleListNode(int x) : val(x), next(NULL) {}

};
DoubleListNode* removeLastKthNode(DoubleListNode *head) {
	if (head == NULL || head->next == NULL)return head;
	DoubleListNode* pre = NULL, *next = NULL;
	while (head != NULL) {
		next = head->next;
		head->next = pre;
		head->last = next;
		pre = head;
		head = next;
	}
	return pre;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值