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)
View Code

进阶:

  给定链表的头结点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)
View Code

 

以上是关于OD统一考试(B卷)寻找链表的中间结点的主要内容,如果未能解决你的问题,请参考以下文章

链表876. 链表的中间结点

删除链表的中间节点和a/b处的节点

Leetcode daily 20/03/23 链表的中间结点

LeetCode876. 链表的中间结点

LeetCode876 链表的中间结点

查看链表的中间结点,链表的逆序,返回链表倒数第k个结点