'''
* 思路
* 1. 编写一个方法,接受head节点,同时接收一个index
* 2. index表示是倒数第index节点
* 3. 先把链表从头到尾遍历,得到总的长度getLength
* 4. 得到size后,我们从链表的第一个开始遍历(size-index)个,就可以得到
* 5. 如果找到返回该节点,否则返回null
'''classListnode(object):def__init__(self,data,next=None):
self.data=data
self.next=nextdefgetSingleLinkedListNodeCount(self,node):if node ==None:return0if node.next==None:return1
p = node
count =0while p:
count +=1
p = p.nextreturn count
defFindLastIndexNode(self,node,k):
length = self.getSingleLinkedListNodeCount(node)
num = length - k
if k <=0or k > length:returnNone
p = node
while p and num >0:
p = p.next
num -=1return p.data
4.链表中环的入口
defEntryNodeOfLoop1(self, pHead):# write code here#遍历链表,环的存在,遍历遇见的第一个重复的即为入口节点
tempList =[]
p = pHead
while p:if p in tempList:return p
else:
tempList.append(p)
p = p.next
5.单链表排序
classSolution:defsortList(self, head):ifnot head ornot head.next:return head # termination.# cut the LinkedList at the mid index.
slow, fast = head, head.nextwhile fast and fast.next:
fast, slow = fast.next.next, slow.next
mid, slow.next= slow.next,None# save and cut.# recursive for cutting.
left, right = self.sortList(head), self.sortList(mid)# merge `left` and `right` linked list and return it.
h = res = ListNode(0)while left and right:if left.val < right.val:
h.next, left = left, left.nextelse:
h.next, right = right, right.next
h = h.next
h.next= left if left else right
return res.nextclassSolution(object):defsortList(self, head):"""
:type head: ListNode
:rtype: ListNode
"""ifnot head ornot head.next:return head
temp = head
node_list =[]while head:
node_list.append(head.val)
head = head.next
node_list.sort()
head = temp
i =0while head:
head.val = node_list[i]
head = head.next
i +=1return temp
6.链表带环
'''
判断链表是否带环:
思路:设定快慢指针,快指针一次走2步,慢指针一次走一步,当快指针=慢指针则带环
循环链表: 最后一个节点指向 头节点
'''# 链表带环classListnode(object):def__init__(self,data,next=None):
self.next=next
self.data = data
classSolution(object):defIscycle(self,head):ifnot head:returnNone
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.nextif slow == fast:print("存在循环链表,节点为:",slow.data)returnTrueprint("不存在循环链表")returnFalse
7.链表的中间节点
'''
查找链表的中间节点:
思路:设定快慢指针,快指针一次走2步,慢指针一次走一步,当快指针走到尾部,慢指针所指向的位置就是中间节点
首先,我们初始化一个节点类,表示链表中的元素,它的属性应该有两个,当前节点的值,和下一个节点的地址
'''classListnode(object):def__init__(self,data,next=None):
self.data=data
self.next=nextclassSolution(object):defmiddleNode(self, head):if head isNone:returnNone
slow = fast = head # 初始化两个指针while fast and fast.next:#while fast.next and fast.next.next则偶数长度,返回第一个中间节点
slow = slow.next# 走一步
fast = fast.next.next# 走两步return slow.data
8.删除链表中的重复节点
'''
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
值得注意的是,本题是不保留重复节点,而在 LeetCode 85题中,保留一个元素。
'''classSolution3:defdeleteDuplication(self, pHead):# write code hereifnot pHead:returnNone
a_list =[]while pHead:
a_list.append(pHead.val)#把所有节点值都存到链表中
pHead = pHead.next
new_list =[i for i in a_list if a_list.count(i)==1]#去掉重复节点if new_list:
root = pHead = ListNode(new_list[0])#初始化头节点for i inrange(1,len(new_list)):
pHead.next= ListNode(new_list[i])#组成链表
pHead = pHead.nextreturn root
else:returnNone
'''
第一步:相加各位的值,不算进位,二进制每位相加就相当于各位做异或操作;
第二步:计算进位值,相当于各位做与操作,再向左移一位。
第三步重复上述两步, 各位相加 ,计算进位值。进位值为0,跳出循环。
'''classSolution:defAdd(self, num1, num2):# write code here
result = num1 ^ num2
carry =(num1 & num2)<<1while carry:
num1 = result
num2 = carry
result =(num1 ^ num2)
carry =(num1 & num2)<<1return result
11.K个一组反转链表
classSolution(object):defreverseKGroup(self, head, k):"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
res =[]while head:
res.append(head.val)
head = head.next
num =len(res)// k #确定是几组k
num_res =len(res)% k #判断是是否有余数
tmp =[]for i inrange(num):
s = res[k*i:k*(i+1)][::-1]
tmp += s
if num_res ==0:
tmp = tmp #为零的话则不需要else:
tmp = tmp + res[-num_res:]#如果余数不为零则需要考虑
root = ListNode(0)
head = root
for i in tmp:
node = ListNode(i)
head.next= node
head = head.nextreturn root.next