OD统一考试(B卷)寻找链表的中间结点
Posted 梦想橡皮擦 Python爬虫、Python爬虫百例入门、
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OD统一考试(B卷)寻找链表的中间结点相关的知识,希望对你有一定的参考价值。
华为 OD 机试【4 大宝典】再次上新题!
① Python 解华为机试题 :https://dream.blog.csdn.net/article/details/129221789
② C++ 解华为机试题:https://dream.blog.csdn.net/article/details/129472919
③ Java 解华为机试题:https://dream.blog.csdn.net/article/details/129652513
④ C 解华为机试题:https://dream.blog.csdn.net/article/details/129658432
本篇题解:寻找链表的中间结点
题目
给定一个单链表 L,请编写程序输出 L 中间结点保存的数据。如果有两个中间结点,则输出第二个中间结点保存的数据。 例如:给定 L 为 1→7→5
,则输出应该为 7
;给定 L 为 1→2→3→4
,则输出应该为 3
。
输入
每个输入包含 11 个测试用例。 每个测试用例第 11 行给出链表首结点的地址、结点总个数正整数 N(N≤105)。结点的地址是 55 位非负整数,NULL
地址用 −1
表示。
接下来有 N 行,每行格式为:
Address Data Next
其中 Address
是结点地址,Data
是该结点保存的整数数据(0≤Data≤108),Next
是下一结点的地址。
输出
对每个测试用例,在一行中输出L 中间结点保存的数据。如果有两个中间结点,则输出第二个中间结点保存的数据。
备注
已确保输入的结点所构成的链表 L 不会成环,但会存在部分输入结点不属于链表 L 情况 。
题解地址
删除链表的中间节点和a/b处的节点
问题描述:
删除链表的中间节点和a/b处的节点
给定链表的头结点head,实现删除链表的中间节点的函数:
例如:
不删除任何节点;
1-->2,删除节点1;
1-->2-->3,删除节点2
1-->2-->3-->4,删除节点2;
1-->2-->3-->4-->5,删除节点3;
分析及解题思路:
对于删除链表中的中间节点而言,当节点数增加2时,要删除的中间节点向后移一位。比如,首先链表中没有节点或节点为1个时,直接返回头结点;当节点数为2个时,直接返回head.next;对于三个节点以上的情况,有如下解决过程:
对于删除链表中的某个节点,要知道该节点的前一个节点的位置,只需将前一个节点的位置的next区域指向要删除节点的下一个位置即可。
当链表节点的个数为3个时,则删除第二个节点,当节点数增加2时,此时要删除的节点就向后移一位。比如,当节点数为4个时,也是删除第二个节点;当节点数为5时,此时要删除第三个节点。所以首先pre指向头节点(pre每次指向要删除节点的前一个节点),cur指向pre节点的下一个节点的下个节点,然后判断当cur的下一个节点存在以及下下个节点存在时,说明在最初节点数为3个的基础上链表节点的个数增加2个,则pre指向后一个节点,cur指向下一个节点的下一个节点;直到cur的下一个节点或者下下个节点不存在时,循环结束,此时pre指向的位置正好是要删除链表中间节点的前一个节点的位置。这时删除节点即可。
代码实现:
1 class Node(object): 2 def __init__(self, data): 3 self.data = data 4 self.next = None 5 6 def createSingleLink(num): 7 head = Node(1) 8 cur = head 9 for i in range(2, num+1): 10 cur.next = Node(i) 11 cur = cur.next 12 return head 13 14 def printSingleLink(head): 15 cur = head 16 while cur: 17 print(cur.data, end=‘‘) 18 if cur.next: 19 print(‘-->‘, end=‘‘) 20 cur = cur.next 21 22 def removeMidNode(head): 23 if head is None or head.next is None: 24 return head 25 if head.next.next is None: 26 return head.next 27 pre = head 28 cur = head.next.next 29 while cur.next and cur.next.next: 30 pre = pre.next 31 cur = cur.next.next 32 pre.next = pre.next.next 33 return head 34 35 if __name__ == ‘__main__‘: 36 singleLinkHead = createSingleLink(9) 37 printSingleLink(singleLinkHead) 38 newSingleLinkHead = removeMidNode(singleLinkHead) 39 print() 40 printSingleLink(newSingleLinkHead)
进阶:
给定链表的头结点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,不删除任何节点。
分析及解题思路:
首先,当给出a和b的值后,要确定删除的是哪个节点,通过下面的式子的结果r来确定要删除的哪个节点,其中n为链表节点的个数:
r = (a * n) / b
最终的r向上取整,例如:
N = 5,a = 3,b = 5
则r = 3,即删除第三个节点;
N = 5,a = 3,b = 4
则r = 3.75,向上取整后删除的节点为第4个节点;
N = 5,a = 2,b = 6
则r = 1.6667,向上取整后删除的节点为第2个节点;
代码实现:
1 import math 2 class Node(object): 3 def __init__(self, data): 4 self.data = data 5 self.next = None 6 7 def createSingleLink(num): 8 head = Node(1) 9 cur = head 10 for i in range(2, num+1): 11 cur.next = Node(i) 12 cur = cur.next 13 return head 14 15 def printSingleLink(head): 16 cur = head 17 while cur: 18 print(cur.data, end=‘‘) 19 if cur.next: 20 print(‘-->‘, end=‘‘) 21 cur = cur.next 22 23 def removeByRatio(head, a, b): 24 if a < 1 or a > b: 25 return head 26 cur = head 27 n = 0 28 while cur: 29 n += 1 30 cur = cur.next 31 r = math.ceil((a * n) / b) 32 if r == 1: 33 head = head.next 34 if r > 1: 35 pre = head 36 while r > 2: 37 r -= 1 38 pre = pre.next 39 pre.next = pre.next.next 40 return head 41 42 if __name__ == ‘__main__‘: 43 singleLinkHead = createSingleLink(5) 44 printSingleLink(singleLinkHead) 45 newSingleLinkHead = removeByRatio(singleLinkHead, 5, 5) 46 print() 47 printSingleLink(newSingleLinkHead)
以上是关于OD统一考试(B卷)寻找链表的中间结点的主要内容,如果未能解决你的问题,请参考以下文章