Leetcode--LinkedList

2. Add Two Numbers

先初始化两个结点,一个用来做head,一个作为指引node不断向下延续的指针,初始化carry为0。当l1或l2或carry有一个存在时,就执行while循环。

  • 需要注意的点有,在while循环一开始就应该先设置v1, v2为0. v1和v2是用来分别存放l1和l2的结点的值的。如果不将他们设为0,当输入为[5], [5]时,程序就会time limit exceeded。因为这时carry总是有值的,这个值并没有被存入linkedlist中,而是一直存在于carry里。
  • 求出digit的值后,n.next = ListNode(digit), n = n.next 不能写成n.val = digit, n = n.next,n一开始是head,并且不需要为val赋值,直接将这个值设为ListNode结点类型就可以了

237. Delete Node in a Linked List

我们都知道删除一个结点,可以通过n.next = n.next.next,这样删除的是n.next,那如果只给你n,要怎样将n自己删除?答案就是先将n.val = n.next.val, 将n.val用n.next.val覆盖,这样就有了两个值重复的节点,然后用上边的语句将n.next删除就行了。这样做其实删除的并不是n,而是n.next,只是将n.next的值赋给了n而已。

21. Merge Two Sorted Lists

当l1和l2都存在时,进行while循环,如果l1 >= l2, 就将n.next = l1, l1 = l1.next, n= n.next, 反之亦然。需要注意的是,等号可以和大于小于任意一个合并,意思就是当出现等于时,就一直连接l1或l2里等于的值,直到等于的值连接完了,再连接另一个List里等于的值。当while循环结束时,因为有可能l1,l2中期中一个依然没有连接完,所以用两个If语句连连接剩下的node

19. Remove Nth Node From End of List

这次是从linkedlist末尾,remove掉第n个元素。并且要求尽量在one pass内完成。
要remove掉一个元素,我们的思路就是找到这个元素的前一个位置. 用两个指针,都从dummy开始,先让指针runner走n步, 这时walker是从runner开始向前数的第n+1个元素,我们就形成了一个窗口。然后开始等速移动这两个指针,直到runner到了最后一个元素,此时walker就在我们想remove的元素的前一个位置。将walker.next = walker.next.next就可以了

24. Swap Nodes in Pairs

交换相邻两个node, 不能仅交换他们的值。思路是要进行三次next重定向。以dummy->1->2->3->4为例:

  1. 要将1.next指向2.next,即3
  2. 要将2.next指向1
  3. 要将dummy.next指向2

思路的关键点在于要用一个临时指针来指向2,即dummy.next.next,这样做的原因是,当我们执行了第一个重定向时,就再也找不到2了,回不去了。所以要在执行第1个步骤时先将2用临时指针标记起来,留作之后使用

temp = dummy.next.next   标记
dummy.next.next = temp.next   步骤1
temp.next = dummy.next    步骤2
dummy.next = temp   步骤3
dummy = dummy.next.next

61. Rotate List

  • 先数出list的长度,len从1开始,到最后一个节点停止。
  • 对k进行mod,k = k%len,这样做是为了节省时间,提高效率,因为如果k==len,那结果就是原来的list。
  • 得到新的k之后,用两个从head开始的指针,进行for循环,这里需要注意的点是:我们想要找到需要rotate的那段list,当循环range(k)次后,fast指针刚好来到需要rotate的list的前一个节点. 原因就是我们需要rotate k个节点,循环k次后,slow不变,依然在原来的位置,fast则正好和slow相差k+1个节点(包括他俩自己),这样就形成了一个窗口。
  • 然后开始同时移动slow和fast, 直到fast来到最后一个节点。此时slow指向了需要rotate的list的前一个节点
  • newhead = slow.next, slow.next = None, fast.next = head 最后返回return newhead

83. Remove Duplicates from Sorted List

当head.next存在时,判断
if head.val == head.next.val: head.next = head.next.next
else: head = head.next

82. Remove Duplicates from Sorted List II

与上一题不同的地方在于,这道题要求将重复的结点都删去,一个都不留。此时我们就需要一个指针来指向第一个重复结点的前一个数字。当重复结点结束时,使得head指针指向重复结点的最后一个数字。这样通过pre.next = head.next就可以把中间所有的重复结点都删掉了。需要注意的点有:

  • 我们用一个bool类型的变量repeat来标记值是否重复,如果head.val == head.next.val我们就将repeat设为true,并向后移动head
  • 当head和head.next值不相等时,就要判断repeat是否为真,若为真,我们就将中间的结点删去,并将head向后移动一位,但注意, pre不能再向后移了,因为若向后移就和head重合了。最后把repeat设为false
  • 当repeat不为真时,我们就直接向后移动head和pre
  • 很重要的一点是,也是corner case, 那就是linkedlist里的节点值全都相等,也就是当while循环结束了,重复的值却依然都在,因为已经遍历到最后一个节点了。这是要多加一个if判断if repeat在while循环外部,如果while循环结束了repeat仍然为真,那我们就指行pre.next = head.next把中间的重复结点都删掉,这点非常重要,很容易遗漏
  • 最后返回dummy.next

86. Partition List

要能知道这道题就是把原来的linkedlist划分为两个,一个比x值小,一个大于等于x的值,然后让第一个linkedlist指向第二个linkedlist,并将第二个linkedlist的最后一个元素指向空就可以了。

  • 需要注意的点有,在将第一个linkedlist指向第二个的时候pointer1.next = dummy2.next, 这里一定要是dummy2.next而不能是dummy

206. Reverse Linked List

用pre来标记head前边的节点,next标记head的下一个节点

while head:
         next = head.next
         head.next = pre
         pre = head
         head = next
return pre

需要注意的是: pre = None,Pre要先初始化为空,每次循环开始要先标记head.next

92. Reverse Linked List II

这道题用上一道题做了subroutine,思路是先找到要reverse的第一个节点的前一个节点start,和最后一个节点的后一个节点end。这个地方画图会更明白一些。然后我们要做的就是对start和end之间的节点用上道题的方法进行reverse。

  • 怎样找到start和end?
    两个while循环,while m!=1:找start,while n!= -1找end。
  • pre的初始化还是空吗?
    不是了,pre的初始化应该是end,先把尾端连接起来
  • reverse中间的节点时,循环结束条件是什么?
    while head != end,注意当这个循环结束时,我们还没有把首端连接起来,要在循环外部加上start.next = pre
  • 找到start和end后,怎样找到要reverse的第一个节点?
    head = start.next, head就是我们要reverse的第一个节点

109. Convert Sorted List to Binary Search Tree

和105,106题有点像,先将linkedlist里的值取出来存到数组里,再根据数组来构造BST.
根:mid = len(list)/2, root = TreeNode(list[mid])
左子树:root.left = self.helper(list[:mid])
右子树:root.right = self.helper(list[mid+1:])

138. Copy List with Random Pointer

整体思路就是将linkedlist存入哈希表中
初始化一个hash table,老指针作为key,新指针作为value。先将linkedlist遍历一遍,存入新指针。
然后进行第二遍遍历,此时所有的node都存在hash table里了,
dic[p2].next = dic.get(p2.next) dic[p2].random = dic.get(p2.random) p2 = p2.next
循环结束后返回return dic.get(head)

141. Linked List Cycle

方法就是一个fast,一个slow指针,分别从头开始往后走,fast每次走两个结点,fast = fast.next.next, slow每次走一个节点,slow = slow.next,循环的判断条件是while fast and fast.next
如果两个指针相遇了,就证明有环,否则就没有环。
为什么两个指针一定会相遇呢?
因为如果环存在,fast先进入,slow后进入。两个指针都进入之后,可以把slow看做前边的那个指针,让fast在后边追赶它。因为两个指针此时都在环内,一个速度是另一个的两倍,所以一定会相遇。并且相遇时fast超过slow一圈

142. Linked List Cycle II

这道题的图片和思路来源:
http://www.cnblogs.com/hiddenfox/p/3408931.html

Paste_Image.png

X为链表起点,Y为圆环起点,Z为slow和fast第一次相遇的点,abc为各段的长度,因为fast速度是slow的两倍,所以fast走过的路长也是slow的两倍,所以有等式2(a+b) = a + b + c + b, 然后我们可以得出a = c!!!这点非常有用。
现在我们想要找到Y, 我们可以让一个指针从x开始,像后走a步,但我们并不知道a有多远 ,也不知道c有多远,我们可以让slow从z出发,当slow和head相遇时,就证明他们都到达了Y点,分别走了相同的步数。此时指针指向的就是圆环起点。

  1. 如何将有环的链表变成单链表(解除环)?
  1. 如何判断两个单链表是否有交点?如何找到第一个相交的节点?

For1 在上一个问题的最后,将c段中Y点之前的那个节点与Y的链接切断即可。

For 2 如何判断两个单链表是否有交点?先判断两个链表是否有环,如果一个有环一个没环,肯定不相交;如果两个都没有环,判断两个列表的尾部是否相等;如果两个都有环,判断一个链表上的Z点是否在另一个链表上。

如何找到第一个相交的节点?求出两个链表的长度L1,L2(如果有环,则将Y点当做尾节点来算),假设L1<L2,用两个指针分别从两个链表的头部开始走,长度为L2的链表先走(L2-L1)步,然后两个一起走,直到二者相遇。

143. Reorder List

1,2,3,4,5,6变成1,6,2,5,3,4, 思路

  1. 将list分为两段:先用slow, fast两个指针找到list的中点,slow.next = h2 用h2代表第二段list的head,然后使slow.next = None
  2. 构建一个reverse函数,将h2作为参数传进去,这个函数的作用时将传进来的list给reverse,并返回最后的头结点(注意应该返回pre,而不是head)
  3. 此时将h2插在h1和h1.next中间,并分别将h1和h2向后移动一个节点。循环判断条件是while h1 and h2:
    不需要返回任何东西,读题一定要读清楚了

147. Insertion Sort List

对Linkedlist进行插入排序,需要注意的有:

  1. 有序序列的最后一个node.next应该为空
  2. 每次从头开始扫描有序的List, 所以有prepre = dummy
  3. while prepre.next.val < cur.val截止时,此时prepre.next并不一定就是pre,所以要将pnext = prepre.next做记录
  4. 如果cur.val>= pre.val,就做自然连接,连接后分别更新cur和pre

148. Sort List

有两种方法:

  1. divide and conqure(merge and sort):新建三个虚拟node, n1,n2,n3,以head.val作为Pivot, 比pivot值小的节点,连在n1后边,与pivot值相等的节点,连在n2后边,比它大的结点,连在n3后边。然后再分别对n1, n3进行self.sortList()操作。最后将三段List连接起来
  2. Quick sort: 将List不断从中间分为两段,并将两段分别进行self.sortList(),然后再一段一段的进行连接。连接时要新建一个虚拟node,在两个list里,谁的值更小就连哪个。

445. Add Two Numbers II

Two stacks

234. Palindrome Linked List

reverse the first half while finding the middle
compare the reversed half with the second half
if fast: slow = slow.next
because the length might be odd, in this case, we don't need to compare the middle node, we need to skip it.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,907评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,546评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,705评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,624评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,940评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,371评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,672评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,396评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,069评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,350评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,876评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,243评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,847评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,004评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,755评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,378评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,266评论 2 259

推荐阅读更多精彩内容