算法总括,010对链表进行重新排序

时间:2019-10-11 02:06来源:编程技术
其他坏习于旧贯、倒霉的行为,独有零次和重重次之分。——不知底何人说的 正文首发于本身的民用博客:尾尾巴部分落 后天的题有一些难度,笔者开头写的晚了。后天写爬虫碰着了

其他坏习于旧贯、倒霉的行为,独有零次和重重次之分。——不知底何人说的

正文首发于本身的民用博客:尾尾巴部分落

后天的题有一些难度,笔者开头写的晚了。后天写爬虫碰着了劳动,头痛了一天。昨日发的晚了,停更独有零次和广大次之分!

链表是面试进程中时常被问到的,这里把剑指offer 和 LeetCode 中的相关主题材料做八个聚集,方便复习。

主题素材陈述:给定链表L0->L2->L3……->Ln-1->Ln把链表重新排序为L0->Ln->L2->Ln-1->L3->Ln-2……需要:在本来链表的根基上进展排序,即不能够报名新的节点;只可以修改节点的next域,不可能修改数据域

难题陈诉:给定单向链表的头指针和二个节点指针,定义三个函数在O时间删除该节点。解题思路澳门金莎娱乐网站,:常规的做法是从链表的头结点开端遍历,找到须求删除的节点的前人节点,把它的 next 指向要去除节点的下壹个节点,平均时间复杂度为O,不知足标题要求。那是还是不是迟早要获取被删去的节点的前多个节点吧?其实不用的。大家能够很方面地获取要删减节点的下多少个节点,假若大家把下八个节点的内容复制到要去除的节点上覆盖原有的剧情,再把下一个节点删除,那就约等于把当下要删减的节点删除了。举个栗子,我们要去除的节点i,先把i的下贰个节点j的剧情复制到i,然后把i的指针指向节点j的下多个节点。此时再删除节点j,其效能刚好是把节点i给删除了。要专一三种情景:

今天的难点的难度是局地,可是还在咱们能分晓的限定内。上面大家来深入分析下那道标题:要将链表的尾声一人接在第三个节点后,首先很容易就会想到:分两重循环,第一重从链表头初阶遍历,第二重正是从尾部开端遍历,然后将尾巴部分节点间接连在外层遍历节点之后就可以,直到链表到中间。当然你们会问怎么从尾巴部分初阶遍历?很轻松,每便都遍历到最后四个,然后将其加到前边;然后下次遍历的时候,还是遍历到最后二个节点,因为最终三个节点正是我们须求管理的节点。那又有人问了,怎么推断是或不是到中游了呢?那也差不离,先遍历链表算出链表的长度,然后去中值,然后再伊始遍历到那个中值,那特别勤奋!!!上面的措施是自己写作品时暂且想的,是或不是看起来没什么难题,唯独!!!实操起来,非常费时,费事,轻巧出错。再正是会令人认为自个儿向来不头脑。。。

  1. 假设链表中唯有贰个节点,即头节点等于要删减的节点,此时大家在剔除节点之后,还要求把链表的头节点设置为NULL。
  2. 一经要刨除的节点位于链表的尾巴,那么它就从未下二个节点,那时我们就要从链表的头节点开首,顺序遍历获得该节点的前序节点,并做到删除操作。

下边正确方法:

观测难点的五个链表:L0->L2->L3……->Ln-1->Ln和L0->Ln->L2->Ln-1->L3->Ln-2……,能够设想一条绳子,上面有三个贰个的结,作者把绳索首尾对接,将绳子对折,是或不是就大约疑似标题标那么,节点地点变动了,当然标题要求更加高点,要变为一条链表。对于链表,你不能够说对折就对折了,自然是要想艺术——>先将链表从当中间断开,然后将后半条链表逆序,然后合併。注意!这里不是一向将其连到前边,而是将后边的每二个节点都插到多少个节点之间。这里就提到到连个主要的操作——怎么样推断链表的高级中学级节点是哪个?以致怎么着统一三个链表?

先来看找出中间节点的方法:前面早就介绍了一种简易的法子,然则要求遍历链表四次,不是我们想看看的图景。我们明天来看八个更加快的主意:

  1. 用两个指针——jump1和jump2。jump1每回向后遍历多个节点;jump2每回向后遍历多少个节点。
  2. 当jump2达到后面部分时(这里会有二种情况,奇数个和偶数个,上边深入分析),jump1刚好是到达链表中间节点。

那边又分二种情状,链表长度为奇数和偶数,那多个是分化的意况——数学难题:

  • 奇数:jump2上涨的幅度为2,最终一回刚好能够遍历到终极三个节点。此时的mid节点取jump1和jump1.next都行。
  • 偶数:jump2增幅为2,是力不能够支遍历到最终三个节点的,只好遍历到倒数第一个节点,下一跳就为空了,能够结合下边包车型客车代码看一下:比方:1->2->3->4#在二次巡回后jump2指向3,依据循环条件,此时是要再进来循环的,#这一次巡回是没难点的,也正是jump2指向None,但是此时来判定是不是进循环就出了难点#因为jump2是空的,它从不next属性,程序在运维是会报错切实细节小编在代码注释里写的十二分掌握了!留心看
 jump1 = head.next # step为1的指针 jump1Pre = head.next # 用于指向jump1的前驱节点 jump2 = head.next # step为2的指针 mid = None # 用于指向链表的重点 while jump2.next is not None: #这句是重点!!当链表长度为偶数,比如:1->2->3->4 #在一次循环后jump2指向3,根据循环条件,此时是要再进入循环的, #这次循环是没问题的,也就是jump2指向None,但是此时来判断是否进循环就出了问题 #因为jump2是空的,它没有next属性,程序在运行是会报错 if jump2.next.next is None: break # 指向下一跳 jump1Pre = jump1 jump1 = jump1.next jump2 = jump2.next.next #这里接着上面的问题,无论是哪种情况退出循环 # 其中间值我都设为jump1后一个, # 1)循环条件退出,说明个数为偶数,选jump1和jump1.next是一样的 # 2)if语句退出,说明链表长度为奇数,但是jump2并没有到最后一个, # 所以其中间值应该是jump1的后一个,这是数学问题,大家自己画画图 mid=jump1.next jump1Pre=jump1 jump1Pre.next = None # 切断

 #逆序后面的链表,这里就不多说了,前面都讲了三个方法了 cur=mid.next#用来逆序链表,指向第2个节点 mid.next=None while cur is not None : next=cur.next cur.next=mid mid=cur cur=next

笔者一向上航海用教室了。上边的是前半有的,下边包车型客车是逆序后的后半局地:链表长度为偶数时,前后三个链表合并时的拍卖顺序:

澳门金莎娱乐网站 1链表长度为偶数这里自身是将四个操作合在联名,作为一回巡回做的干活,还是能够将1步充任三遍巡回方法。相当多书上是后世,小编觉着对于新书,笔者要么两步操作看的更掌握!从图上得以看出5以此节点作者并未接上,因为在自身的循环里它完不成,要求在终结后再接上。图中固然把5以此节点直接拿掉,就是奇数长度的链表的操作进度。上述,看图细细咀嚼。代码:

 # 这里是难点 # 合并head和mid,mid无头节点 curHead=head.next # 指向前半条链表的第一个节点 curmid=mid # 指向后半条链表的第一个节点,从这里也可理解前面的mid节点的选取, #因为我要的是后半条,自然得要中间节点的后一个 while curHead.next is not None: #因为取中间节点的原因,前半条链表的长度大于等于后半条 nexthead = curHead.next #记录head的下一个节点 #这里你看我前面画的图 curHead.next = curmid nextmid = curmid.next #记录mid的下一个节点 curmid.next = nexthead curHead = nexthead curmid = nextmid # 这是前半条链表导等于后半条链表, # 也就是原链表产的长度为偶数的情况,因为前面循环只处理的 # 只是将head连到mid,再从mid连到head,每次处理两个链接, # 但是偶数个节点之间应该有奇数个链接,这里是mid的最后一个节点没有处理 if cur mid is not None: curHead.next=curmid return head

如上的代码小编是写在了多个函数里,上边被笔者分开了,方便我们看。上边来试一试这些算法是还是不是精确,笔者试了长短分别为:0,1,2,3,9,10,这几组:

if __name__ == '__main__': head=creatLink print("BeforeReverse:") cur = head.next while cur != None: print cur = cur.next head=xReverese print("nAfterReverse:") cur = head.next while cur != None: print cur = cur.next

出口结果:

澳门金莎娱乐网站 20澳门金莎娱乐网站 31澳门金莎娱乐网站 42澳门金莎娱乐网站 53澳门金莎娱乐网站 69澳门金莎娱乐网站 710

地点的这种输入能够印证大家的代码是不是结实,不能因为一遍对了,就感到整个程序都对了。全总的代码:

class LNode: def __init__: self.data=arg self.next=None"""题目描述:给定链表L0->L2->L3……->Ln-1->Ln把链表重新排序为L0->Ln->L2->Ln-1->L3->Ln-2……要求:在原来链表的基础上进行排序,即不能申请新的节点;只能修改节点的next域,不能修改数据域方法:先找到链表的中间节点,并将原链表拆分成两个子链表,将后面的子链表逆序,在将两个子链表合成最终链表"""def creatLink: i = 1 head = LNode tmp = None cur = head while i <= x: tmp = LNode cur.next = tmp cur = tmp i += 1 return headdef xReverese: #判断链表是否为空,或者只有一个元素,或者只有两个元素 if head is None or head.next is None or head.next.next is None: return head # 寻找链表中间节点 jump1 = head.next # step为1的指针 jump1Pre = head.next # 用于指向jump1的前驱节点 jump2 = head.next # step为2的指针 mid = None # 用于指向链表的重点 while jump2.next is not None: #这句是重点!!当链表长度为偶数,比如:1->2->3->4 #在一次循环后jump2指向3,根据循环条件,此时是要再进入循环的, #这次循环是没问题的,也就是jump2指向None,但是此时来判断是否进循环就出了问题 #因为jump2是空的,它没有next属性,程序在运行是会报错 if jump2.next.next is None: break # 指向下一跳 jump1Pre = jump1 jump1 = jump1.next jump2 = jump2.next.next #这里接着上面的问题,无论是哪种情况退出循环 # 其中间值我都设为jump1后一个, # 1)循环条件退出,说明个数为偶数,选jump1和jump1.next是一样的 # 2)if语句退出,说明链表长度为奇数,但是jump2并没有到最后一个, # 所以其中间值应该是jump1的后一个,这是数学问题,大家自己画画图 mid=jump1.next jump1Pre=jump1 jump1Pre.next = None # 切断 #逆序后面的链表,这里就不多说了,前面都讲了三个方法了 cur=mid.next#用来逆序链表,指向第2个节点 mid.next=None while cur is not None : next=cur.next cur.next=mid mid=cur cur=next # 这里是难点 # 合并head和mid,mid无头节点 curHead=head.next # 指向前半条链表的第一个节点 curmid=mid # 指向后半条链表的第一个节点,从这里也可理解前面的mid节点的选取, #因为我要的是后半条,自然得要中间节点的后一个 while curHead.next is not None: #因为取中间节点的原因,前半条链表的长度大于等于后半条 nexthead = curHead.next #记录head的下一个节点 #这里你看我前面画的图 curHead.next = curmid nextmid = curmid.next #记录mid的下一个节点 curmid.next = nexthead curHead = nexthead curmid = nextmid # 这是前半条链表导等于后半条链表, # 也就是原链表产的长度为偶数的情况,因为前面循环只处理的 # 只是将head连到mid,再从mid连到head,每次处理两个链接, # 但是偶数个节点之间应该有奇数个链接,这里是mid的最后一个节点没有处理 if cur mid is not None: curHead.next=curmid return headif __name__ == '__main__': head=creatLink print("BeforeReverse:") cur = head.next while cur != None: print cur = cur.next head=xReverese print("nAfterReverse:") cur = head.next while cur != None: print cur = cur.next

明天晚了,因为内容比很多,小编也不想糊弄本身,更不想糊弄大家,笔者是不会停更的!!!加油!!!

只怕那么,小编如故的愿意扶持我们——微信、简书:Dkider。语句千万条,正确第一条。代码不标准,手指两行泪。

澳门金莎娱乐网站 8Dkider

参谋代码

public static ListNode deleteNode(ListNode head, ListNode toBeDeleted) { // 如果输入参数有空值就返回表头结点 if (head == null || toBeDeleted == null) { return head; } // 如果删除的是头结点,直接返回头结点的下一个结点 if (head == toBeDeleted) { return head.next; } // 下面的情况链表至少有两个结点 // 在多个节点的情况下,如果删除的是最后一个元素 if (toBeDeleted.next == null) { // 找待删除元素的前驱 ListNode tmp = head; while (tmp.next != toBeDeleted) { tmp = tmp.next; } // 删除待结点 tmp.next = null; } // 在多个节点的情况下,如果删除的是某个中间结点 else { // 将下一个结点的值输入当前待删除的结点 toBeDeleted.value = toBeDeleted.next.value; // 待删除的结点的下一个指向原先待删除引号的下下个结点,即将待删除的下一个结点删除 toBeDeleted.next = toBeDeleted.next.next; } // 返回删除节点后的链表头结点 return head; } 

问题陈述:输出一个单链表的逆序反转后的链表。解题思路:用七个有的时候指针 prev、cur、next 在链表上循环叁遍就可以。

[剑指offer] 从尾到头打字与印刷链表[剑指offer] 反转链表

难点呈报:给定八个单向链表的头结点head,以致四个整数from和to,在单链表上把第from个节点和第to个节点这一片段进行反转

举例:1->2->3->4->5->null, from = 2, to = 4结果:1->4->3->2->5->null

public ListNode reverseBetween(ListNode head, int m, int n) { if (head == null) return null; if (head.next == null) return head; int i = 1; ListNode reversedNewHead = null;// 反转部分链表反转后的头结点 ListNode reversedTail = null;// 反转部分链表反转后的尾结点 ListNode oldHead = head;// 原链表的头结点 ListNode reversePreNode = null;// 反转部分链表反转前其头结点的前一个结点 ListNode reverseNextNode = null; while (head != null) { if  { break; } if (i == m - 1) { reversePreNode = head; } if (i >= m && i <= n) { if  { reversedTail = head; } reverseNextNode = head.next; head.next = reversedNewHead; reversedNewHead = head; head = reverseNextNode; } else { head = head.next; } i++; } reversedTail.next = reverseNextNode; if (reversePreNode != null) { reversePreNode.next = reversedNewHead; return oldHead; } else { return reversedNewHead; }}

主题材料汇报:给定一个单链表,设计四个算法达成链表向右旋转 K 个岗位。比如: 给定 1->2->3->4->5->6->NULL, K=3则4->5->6->1->2->3->NULL解题思路

  • 方法一 双指南针,快指针先走k步,然后三个指针一齐走,当快指针走到结尾时,慢指针的下二个地点是新的一一的头结点,那样就可以旋转链表了。
  • 方法二 先遍历整个链表获得链表长度n,然后此时把链表头和尾链接起来,在以往走n - k % n个节点就到达新链表的头结点前一个点,这时断开链表就能够。

措施二代码:

public class Solution { { public ListNode rotateRight(ListNode head, int k) { if  return null; int n = 1; ListNode cur = head; while  { ++n; cur = cur.next; } cur.next = head; int m = n - k % n; for (int i = 0; i < m; ++i) { cur = cur.next; } ListNode newhead = cur.next; cur.next = NULL; return newhead; }};

难点陈说:删除单链表倒数第 n 个节点,1 <= n <= length,尽量在一回遍历中成就。解题思路:双指针法,找到尾数第 n+1 个节点,将它的 next 指向尾数第 n-1个节点。

[剑指offer] 链表中倒数第k个结点

主题材料汇报:求单链表的中游节点,假设链表的尺寸为偶数,重返中间四个节点的任意一个,若为奇数,则赶回中间节点。解题思路:快慢指针,慢的走一步,快的走两步,当快指针到达尾节点时,慢指针移动到中路节点。

// 遍历一次,找出单链表的中间节点public ListNode findMiddleNode(ListNode head) { if (null == head) { return; } ListNode slow = head; ListNode fast = head; while (null != fast && null != fast.next) { fast = fast.next.next; slow = slow.next; } return slow;}

难题陈述: 给定二个单链表和数值x,划分链表使得全体小于x的节点排在大于等于x的节点此前。

public class Solution { /** * @param head: The first node of linked list. * @param x: an integer * @return: a ListNode */ public ListNode partition(ListNode head, int x) { // write your code here if(head == null) return null; ListNode leftDummy = new ListNode; ListNode rightDummy = new ListNode; ListNode left = leftDummy, right = rightDummy; while (head != null) { if (head.val < x) { left.next = head; left = head; } else { right.next = head; right = head; } head = head.next; } right.next = null; left.next = rightDummy.next; return leftDummy.next; }}

难题陈说:你有五个用链表代表的整数,此中每一种节点包括一个数字。数字存款和储蓄根据在本来整数中相反的依次,使得第一个数字位于链表的最初。写出二个函数将多个整数相加,用链表情势重临和。解题思路:做个巡回,对每一个人举办操作:

当前位:(A[i]+B[i])%10进位:(A[i]+B[i])/10

public class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode c1 = l1; ListNode c2 = l2; ListNode sentinel = new ListNode; ListNode d = sentinel; int sum = 0; while (c1 != null || c2 != null) { sum /= 10; if (c1 != null) { sum += c1.val; c1 = c1.next; } if (c2 != null) { sum += c2.val; c2 = c2.next; } d.next = new ListNode; d = d.next; } if (sum / 10 == 1) d.next = new ListNode; return sentinel.next; }}

问题汇报:在O时间内对链表进行排序。立即排序

public ListNode sortList(ListNode head) { //采用快速排序 quickSort(head, null); return head;}public static void quickSort(ListNode head, ListNode end) { if (head != end) { ListNode node = partion(head, end); quickSort(head, node); quickSort(node.next, end); }}public static ListNode partion(ListNode head, ListNode end) { ListNode p1 = head, p2 = head.next; //走到末尾才停 while (p2 != end) { //大于key值时,p1向前走一步,交换p1与p2的值 if (p2.val < head.val) { p1 = p1.next; int temp = p1.val; p1.val = p2.val; p2.val = temp; } p2 = p2.next; } //当有序时,不交换p1和key值 if (p1 != head) { int temp = p1.val; p1.val = head.val; head.val = temp; } return p1;}

归并列排在一条线序

public ListNode sortList(ListNode head) { //采用归并排序 if (head == null || head.next == null) { return head; } //获取中间结点 ListNode mid = getMid; ListNode right = mid.next; mid.next = null; //合并 return mergeSort(sortList, sortList;}/** * 获取链表的中间结点,偶数时取中间第一个 * * @param head * @return */private ListNode getMid(ListNode head) { if (head == null || head.next == null) { return head; } //快慢指针 ListNode slow = head, quick = head; //快2步,慢一步 while (quick.next != null && quick.next.next != null) { slow = slow.next; quick = quick.next.next; } return slow;}/** * * 归并两个有序的链表 * * @param head1 * @param head2 * @return */private ListNode mergeSort(ListNode head1, ListNode head2) { ListNode p1 = head1, p2 = head2, head; //得到头节点的指向 if (head1.val < head2.val) { head = head1; p1 = p1.next; } else { head = head2; p2 = p2.next; } ListNode p = head; //比较链表中的值 while (p1 != null && p2 != null) { if (p1.val <= p2.val) { p.next = p1; p1 = p1.next; p = p.next; } else { p.next = p2; p2 = p2.next; p = p.next; } } //第二条链表空了 if (p1 != null) { p.next = p1; } //第一条链表空了 if (p2 != null) { p.next = p2; } return head;}

主题材料叙述:输入五个没趣递增的链表,输出多个链表合成后的链表,当然大家须要合成后的链表满足单调不减法则。

[剑指offer] 合併五个排序的链表

标题陈诉:输入二个错落有致链表(每一种节点中有节点值,以致多个指针,一个针对性下二个节点,另贰个卓越指针指向任意五个节点),重回结果为复制后复杂链表的head。(注意,输出结果中请不要回来参数中的节点援用,不然判题程序会直接重返空)

[剑指offer] 复杂链表的复制

难题陈说:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,再次来到链表头指针。 举个例子,链表1->2->3->3->4->4->5 管理后为 1->2->5

[剑指offer] 删除链表中另行的结点

主题材料汇报:推断一个单链表是还是不是有环深入分析:快慢指针,慢指针每趟活动一步,快指针每一遍运动两步,若是存在环,那么四个指针一定会在环内相遇。

难点汇报:决断单链表是或不是有环,要是有,找到环的入口点解题思路:在第 5 题七个指针相遇后,让内部一个指针回到链表的尾部,另贰个指南针在原地,同期往前每一次走一步,当它们重新际遇时,正是在环路的入口点。

[剑指offer] 链表中环的入口结点

主题材料陈诉:给出三个无环单链表解题思路

  • 方法一 最直白的章程是剖断 A 链表的各样节点是或不是在 B 链表中,可是这种措施的大运复杂度为 O * Length。
  • 方法二 转化为环的标题。把 B 链表接在 A 链表后边,假诺得到的链表有环,则印证七个链表相交。能够事先斟酌过的速度指针来推断是或不是有环,然则此地还恐怕有更简便易行的艺术。倘诺B 链表和 A 链表相交,把 B 链表接在 A 链表后边时,B 链表的持有节点都在环内,所以那时候只须要遍历 B 链表,看是还是不是会重临起源就足以判明是或不是相交。那些措施需求先遍历贰遍 A 链表,找到尾节点,然后还要遍历三次 B 链表,判定是或不是产生环,时间复杂度为 O + Length。
  • 方法三 除了转会为环的难点,还足以应用“要是五个链表相交于某一节点,那么未来的节点都是集体全数的”那一个天性,如若八个链表相交,那么最后三个节点分明是集体全部的。所以可以摄取别的一种解法,先遍历 A 链表,记住尾节点,然后遍历 B 链表,相比较三个链表的尾节点,假如同样则相交,不一致则不相交。时间复杂度为 O + Length,空间复杂度为 O,思路比解法 2 更简便易行。

措施三的代码:

public boolean isIntersect(ListNode headA, ListNode headB) { if (null == headA || null == headB) { return false; } if (headA == headB) { return true; } while (null != headA.next) { headA = headA.next; } while (null != headB.next) { headB = headB.next; } return headA == headB;}

标题陈说:找到多少个无环单链表第三个相交点,倘使不相交再次回到空,需要在线性时间复杂度和常量空间复杂度内形成。解题思路

  • 方法一 假诺七个链表存在公共结点,那么它们从集体结点开头一向到链表的最后都以一样的,因而我们只供给从链表的终极初阶,往前寻觅,找到最终三个平等的结点就能够。但是难点给出的单向链表,大家不得不在那从前向后查找,那时,大家就足以依靠栈来完毕。先把三个链表依次装到三个栈中,然后相比七个栈的栈顶结点是不是一致,假如一致则出栈,要是不相同,这最终一样的结点就是大家要的重临值。
  • 方法二 先找寻2个链表的长度,然后让长的先走五个链表的尺寸差,然后再一齐走,直到找到第多个国有结点。
  • 方法三 由于2个链表都尚未环,我们得以把第3个链表接在第一个链表前边,这样就把标题转化为求环的入口节点问题。
  • 方法四 七个指针p1和p2分别指向链表A和链表B,它们同期向前走,当走到尾节点时,转向另三个链表,例如p1走到链表 A 的尾节点时,下一步就走到链表B,p2走到链表 B 的尾节点时,下一步就走到链表 A,当p1==p2 时,正是链表的相交点

方法四的代码:

public ListNode getIntersectionNode(ListNode headA, ListNode headB) { if (null == headA || null == headB) { return null; } if (headA == headB) { return headA; } ListNode p1 = headA; ListNode p2 = headB; while  { // 遍历完所在链表后从另外一个链表再开始 // 当 p1 和 p2 都换到另一个链表时,它们对齐了: // 如果链表相交,p1 == p2 时为第一个相交点 // 如果链表不相交,p1 和 p2 同时移动到末尾,p1 = p2 = null,然后退出循环 p1 = (null == p1) ? headB : p1.next; p2 = (null == p2) ? headA : p2.next; } return p1;}

[剑指offer] 四个链表的第叁个国有结点

标题陈说:上边的标题是针对无环链表的,假使是链表有环吗?解题思路:假使四个有环单链表相交,那么它们必然共有三个环,即环上的自由三个节点都留存于多个链表上。由此得以先用此前快慢指针的诀窍找到七个链表中位居环内的七个节点,若是相交的话,七个节点在多少个环内,那么移动内部一个节点,在三次循环内确定能够与其他一个节点相遇。

编辑:编程技术 本文来源:算法总括,010对链表进行重新排序

关键词: