删除链表的a/b处结点

删除链表的a/b处结点

问题重述:

给定链表的头节点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,不删除任何结点

问题分析:

看到删除结点,我们很快会想到使用快慢指针,但是本题删除的结点没有规律可循,通过观察我们可以发现,如果将r的取值乘以链表的长度,剩余的值向上取整就是我们要删除的结点位置,因此我们使用两遍遍历来确定要删除的结点,第一次遍历获取链表长度n,r = n*(a/b),将r向上取整就可以得到要删除的节点位置,然后第二次遍历链表,将对应的结点删除

解法:

遍历链表

解题:

代码:
public static Node deleteNode(Node head,int a,int b) {
		// 先对特殊情况进行处理
		if(b == 0) {
			throw new RuntimeException("b不能为0");
		}else if(a < 1 || a > b) {
			// 当a<=0的时候,a/b<0,不删除结点,a>b的时候,a/b>1,也不删除结点
			// 这里不需要判断head为null,如果为null,会直接返回null
			return head;
		}
		// 接下来是正常情况
		// 第一次遍历,计算链表的长度
		int n = 0;
		Node node = head;
		while(node != null) {
			n++;
			node = node.next;
		}
		// 计算要删除的结点
		n = (int) Math.ceil((double) (n*a)/(double)b);
		// 第二次遍历,删除结点
		node = head;
		if(n == 1) {
			// 当n=1的时候,删除头节点
			head = head.next;
		}else if(n > 1) {
			while (--n != 1) {
				// 使用1作为循环停止条件是为了得到要删除结点的上一个结点
				node = node.next;
			}
			node.next = node.next.next;
		}
		return head;
	}
代码解析:

本题的重点在于找到要删除的结点位置,根据题目给出的要求,我们可以知道需要的到删除结点的位置需要知道链表的长度,我们第一遍遍历得到链表的长度,然后得到我们的删除结点位置,第二次遍历就可以删除节点了,当中还要注意一个特殊情况,如果我们要删除的结点是头节点,我们直接删除即可,如果不是头节点就使用while循环进行遍历,为了便于操作,我们遍历到删除结点的上一个结点就停止,这样子方便删除结点

posted @   foldn  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示