文章目录
- 前言
- 1. LeetCode21: 合并两个有序链表
- 2. LeetCode237: 删除链表中的节点
- 3. 剑指 Offer 18: 删除链表的节点
- 4. LeetCode234: 回文链表
- 5. 面试题 02.02: 返回倒数第 k 个节点
- 6. LeetCode83:删除排序链表中的重复元素
- 7. LeetCode1290:二进制链表转整数
- 结束语
前言
刷题,尤其是像我这种刚开始刷题的新手,最重要的是要先有个能够执行的算法,能出个结果,即使这个算法很笨,结果很差,也没事,然后再在其基础之上进行改进算法,去做优化,先易后难,一定要思考,画画图,がんばれ(ง •̀_•́)ง!!!
为了方便调试自己的代码,使其能直接运行在LeetCode上,所以,我根据前面几篇博客重新定义了以下函数:
函数名 | 功能 |
---|---|
CreateSingleLinkList(list) | 传入一个数组,将数组转换成无头结点的单链表 |
TraverseList(linklist) | 传入一个单链表,将其节点的值打印出来 |
class ListNode(object):
def __init__(self, val=None, next=None):
self.val = val
self.next = next
class LeetCodeSingleLinkList(object):
def __init__(self):
self.__head = ListNode(None)
def CreateSingleLinkList(self, val_list):
prehead = self.__head
for val in val_list:
new_node = ListNode(val)
prehead.next = new_node
prehead = prehead.next
# 第一个节点是头结点, 所以要返回链表的下一个节点
# 即与LeetCode的保持一致
return self.__head.next
def TraverseList(result):
# result是不含头结点的
while result:
print(result.val, end=' ')
result = result.next
print('')
if __name__ == '__main__':
l1 = LeetCodeSingleLinkList().CreateSingleLinkList([1, 2, 4])
TraverseList(l1)
这里是LeetCode中有关链表的题库。另外还需要注意,val的数据类型,我这里统一定义为了None。
1. LeetCode21: 合并两个有序链表
LeetCode的第21题:合并两个有序链表。
看到这个题,很大可能想到的就是遍历两个链表,然后进行比较,所以就有了一个遍历的条件,即链表L1和链表L2都不为空。
这里我们采用带头结点的单链表比较方便,我们可以定义一个指针prev,不断地去比较链表L1和链表L2对应的值,如果L1的值小,就将指针prev指向L1,然后L1后移,继续用其第二个结点的值与L2的第一个结点的值比较,每比较完一次,prev都要后移,指向新的结点,就这样遍历一遍。如果链表L1和链表L2的长度不一致,那么指针prev最后将指向较长的那个链表。
实现代码如下:
def mergeTwoLists(l1, l2):
prevhead = ListNode(None)
prev = prevhead
while l1 and l2:
if l1.val <= l2.val:
prev.next = l1
l1 = l1.next
else:
prev.next = l2
l2 = l2.next
prev = prev.next
prev.next = l1 if l1 else l2
# 返回不带头结点的链表
return prevhead.next
运行结果,emmmm:
2. LeetCode237: 删除链表中的节点
LeetCode的第237题:删除链表中的节点。
这个题给我的感觉就是比较坑,看到这个就先想到了双链表找前驱结点,或者用单链表带两个指针(一前一后)也可以找到,然后就不加思索的实现了,具体代码详见下面的3.3 剑指 Offer 18: 删除链表的节点。
然后提交的时候发现,函数没有传入链表,只传入了需要被删除的结点,而且还不要返回结果,莫名其妙(•́へ•́╬)懵圈。然后看了官方题解,才理解。。。。。。就是直接把要被删除节点的值被其下一个节点的值给覆盖掉,简单粗暴!!!∑(゚Д゚ノ)ノ就是没想到,看来还是涉世未深呐(这是我LeetCode简单系列的第二题(︶.̮︶))。
代码如下:
def deleteNode(node):
# 简单粗暴
# 237. 删除链表中的节点
node.val = node.next.val
node.next = node.next.next
代码如下:
只击败了18%的用户,看来还有很大的提升空间呐!
3. 剑指 Offer 18: 删除链表的节点
剑指 Offer的第18题:删除链表中的节点。
这个题才比较正常嘛,注意要看看题目的说明以及官方给的函数参数,单链表实现代码如下:
def deleteNode(head, val):
# 给链表加上一个头结点
fakehead = ListNode(None)
fakehead.next = head
prehead = fakehead
while prehead.next:
result = prehead
prehead = prehead.next
if prehead.val == val:
if prehead.next is None:
result.next = None
else:
result.next = prehead.next
return fakehead.next
return fakehead.next
运行如下:
4. LeetCode234: 回文链表
LeetCode第234题:回文链表。
官方给的依旧是单链表,另外,题目中只是判断是否为回文链表,即结果返回是布尔值True或False,enmmm,既然这样,那完全可以用数组实现,哈哈哈哈哈哈,前面博客也说了,在Python中,数组和字典是基本的数据结构,我们可以基于这两种结构构造其他的数据结构。
大致就是将单链表每个节点的值放在数组里,因为回文链表是个对称的结构,回文数组也是,只需判断原数组与翻转后的数组是否一样即可。
代码如下:
def isPalindrome(head):
prehead = head
fake_list = []
while prehead:
fake_list.append(prehead.val)
prehead = prehead.next
return fake_list == fake_list[::-1]
运行结果如下:
5. 面试题 02.02: 返回倒数第 k 个节点
面试题 02.02:返回倒数第 k 个节点。
可以做成两个指针front和rear,两个指针的间距为 k k k,当后面那个指针rear走到最后时,前面的front指针就来到了倒数第 k k k个节点。
def kthToLast(head, k):
front = head
rear = head
for i in range(k):
rear = rear.next
while rear:
front = front.next
rear = rear.next
return front.val
运行结果如下:
6. LeetCode83:删除排序链表中的重复元素
LeetCode第83题:删除排序链表中的重复元素。
一失足成千古恨呐,本来是想执行一下代码,结果点成提交了(’∇’)シ┳━┳,少了一个条件。这个题还是很简单的(本来练习的就是简单题),题目中也说了是一个排序链表,如此就直接判断当前结点的值与其后继节点的值是否一样,不一样的话指针后移;若值一样,则将当前结点的next指向其后继结点的后继结点,最后返回处理后的链表。
def deleteDuplicates(head):
prehead = head
while prehead and prehead.next:
if prehead.val == prehead.next.val:
prehead.next = prehead.next.next
else:
prehead = prehead.next
return head
运行结果如下:
7. LeetCode1290:二进制链表转整数
LeetCode第1290题:二进制链表转整数。
这个题目就是个二进制转十进制,不同的是这次我们不是从最低位开始,而是要从最高位,这也很容易。在学习C语言时就晓得十进制转二进制,就是不断除2,然后余数最下面的就是最高位,就像下面这样子:
13的二进制就是1101,如果从最高位开始将其转换为十进制就是: 2 × 0 + 1 = 1 − − > 2 × 1 + 1 = 3 − − > 2 × 3 + 0 = 6 − − > 2 × 6 + 1 = 13 2\times0+1=1-->2\times1+1=3-->2\times3+0=6-->2\times6+1=13 2×0+1=1−−>2×1+1=3−−>2×3+0=6−−>2×6+1=13,代码实现如下:
def getDecimalValue(head):
prehead = head
result = 0
while prehead:
result = 2 * result + prehead.val
prehead = prehead.next
return result
运行结果如下:
当然,在Python可以直接将二进制转换成十进制,用int()函数就可以,代码如下:
def getDecimalValue(head):
prehead = head
result = '0b'
while prehead:
result += str(prehead.val)
prehead = prehead.next
return int(result, 2)
运行结果如下:
结束语
虽然以前学过数据结构,但平时没有刷过题,这也是第一次刷题,哈哈哈惭愧惭愧,所以就从LeetCode的简单题目入手,然后慢慢加深加大难度。做了这几个题,我觉得对于我这种新手来说,还是要画画图,需要的话在调试一下,哈哈哈哈,加油(ง •̀_•́)ง