链表问题03:删除链表的中间节点和a/b处的节点

【题目】

给定链表的头节点head,实现删除链表的中间节点的函数。

例如:

链表为空或长度为1,不删除任何节点;

1 -> 2,删除节点1;

1 -> 2 -> 3,删除节点2;

1 -> 2 -> 3 -> 4,删除节点2;

1 -> 2 -> 3 -> 4 -> 5,删除节点3;

 

进阶:

给定链表的头节点head、整数a和b,实现删除位于a/b处节点的函数。

例如:

链表:1 -> 2 -> 3 -> 4 -> 5,假设a/b的值为r。

如果r等于0,不删除任何节点;

如果r在区间(0,1/5]上,删除节点1;

如果r在区间(1/5,2/5]上,删除节点2;

如果r在区间(2/5,3/5]上,删除节点3;

如果r在区间(3/5,4/5]上,删除节点4;

如果r在区间(4/5,1]上,删除节点5;

如果r大于1,不删除任何节点。

 

【解答1】

分析原问题,如果链表为空或者长度为1,,不需要调整,则直接返回;如果链表的长度为2,将头节点删除即可;当链表长度到达3,应该删除第2个节点;当链表的长度为4,应该删除第2个节点;当链表的长度为5,应该删除第3个节点……也就是链表长度每增加2(3,5,7……),要删除的节点就后移一个节点。

 

【代码实现1】

struct Node{
	int value;
	Node *next;
	Node(int data){
		value = data;
	}
};

static Node *removeMidNode(Node *head){
	if (head == nullptr || head->next == nullptr){
		return head;
	}
	if (head->next->next == nullptr){
		return head->next;
	}
	Node *pre = head;
	Node *cur = head->next->next;
	while (cur->next != nullptr && cur->next->next != nullptr){
		pre = pre->next;
		cur = cur->next->next;
	}
	pre->next = pre->next->next;
	return head;
}

 

【解答2】

对于进阶问题,如何根据链表的长度n,以及a与b的值决定该删除的节点是哪一个节点。根据如下方法:先计算double r = ((double)(a*n)) / ((double)b)的值,然后r向上取整后的整数值代表该删除的节点是第几个节点。

 

【代码实现2】

static Node *removeByRatio(Node *head, int a, int b){
	if (a < 1 || a > b){
		return head;
	}
	int n = 0;
	Node *cur = head;
	while (cur != nullptr){
		n++;
		cur = cur->next;
	}
	n = ceil((double)(a * n) / b);
	if (n == 1){
		head = head->next;
	}
	if (n > 1){
		cur = head;
		while (--n != 1){
			cur = cur->next;
		}
		cur->next = cur->next->next;
	}
	return head;
}

 

【来源】

《程序员代码面试指南(IT名企算法与数据结构题目最优解)》左程云

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值