链表题目及逻辑

链表题目及逻辑

1. BM1 反转链表

下面第一个代码,尽管是对的,但对于下面的题型来说,第二种逻辑是最合适的;其中cur指向cur.next.next;这里要求cur.next不为空。

class Solution:
    def ReverseList(self , head: ListNode) -> ListNode:
        # write code here
        cur = ListNode(-1)
        while head:
            tmp = head.next
            head.next = cur.next 
            cur.next = head 
            head = tmp 
        return cur.next 
class Solution:
    def ReverseList(self , head: ListNode) -> ListNode:
        # write code here
        if not head:
            return head 

        cur = ListNode(-1)
        cur.next = head 
        while head.next:
            tmp = head.next
            head.next = tmp.next 
            tmp.next = cur.next 
            cur.next = tmp 
        return cur.next 

2. BM2 链表内指定区间反转

class Solution:
    def reverseBetween(self , head: ListNode, m: int, n: int) -> ListNode:
        # write code here
        res  = ListNode(-1)       # 头节点
        res.next = head 

        pre = res                 # 第m-1个节点
        cur = res.next            # 第m个节点
        for i in range(m-1):
            pre = pre.next 
            cur = cur.next 
        # cur和pre不动
        for i in range(m, n):
            tmp = cur.next 
            cur.next = tmp.next 
            tmp.next = pre.next 
            pre.next = tmp 
        
        return res.next

3. BM3 链表中的节点每k个一组翻转

class Solution:
    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        # write code here
        # 初始化结点
        res = ListNode(-1)
        res.next = head 

        # 统计链表节点数
        num = 0 
        while head:
            head = head.next
            num += 1
        
        cur = res
        head = res.next 
        for i in range(num//k):
            for j in range(k-1):
                tmp = head.next 
                head.next = tmp.next 
                tmp.next = cur.next 
                cur.next = tmp 
            cur = head 
            head = head.next 
        return res.next 
4. BM4 合并两个排序的链表
class Solution:
    def Merge(self , pHead1: ListNode, pHead2: ListNode) -> ListNode:
        # write code here

        res = ListNode(-1)
        cur = res

        while pHead1 and pHead2:
            if pHead1.val >= pHead2.val:
                cur.next = pHead2
                pHead2 = pHead2.next
            else:
                cur.next = pHead1
                pHead1 = pHead1.next
            cur = cur.next
        
        cur.next = pHead1 if pHead1 else pHead2

        return res.next
5. BM5 合并k个已排序的链表

通过递归的方法将k个已排序链表转化为两个已排序链表

import sys 
# 甚至递归深度
sys.setrecursionlimit(100000)

class Solution:
    def mergeKLists(self , lists: List[ListNode]) -> ListNode:
        # write code here
        if len(lists)==0:
            return None

        return self.divideMerge(lists, 0, len(lists)-1)

    
    def divideMerge(self, lists, left, right):
        # 二分递归
        if right <= left:
            return lists[left]

        mid = (right - left)//2 + left
        return self.merge2(self.divideMerge(lists, left, mid), self.divideMerge(lists, mid +1, right))

    def merge2(self, pHead1, pHead2):
        # 合并两个升序链表
        if not pHead1:
            return pHead2
        if not pHead2:
            return pHead1

        res = ListNode(-1)
        cur = res

        while pHead1 and pHead2:
            if pHead1.val >= pHead2.val:
                cur.next = pHead2
                pHead2 = pHead2.next
            else:
                cur.next = pHead1
                pHead1 = pHead1.next
            cur = cur.next

        cur.next = pHead1 if pHead1 else pHead2

        return res.next
6. BM6 判断链表中是否有环

双指针的运用

class Solution:
    def hasCycle(self , head: ListNode) -> bool:
        slow, fast = head, head 

        while(fast):
            if fast.next and fast.next.next:
                fast = fast.next.next
                slow = slow.next
            else:
                break
            if slow == fast:
                return True  
        return False
7. BM7 链表中环的入口结点

我的逻辑就是只要记住这题能推理就行

class Solution:
    def EntryNodeOfLoop(self, pHead):
        # write code here
        slow, fast = pHead, pHead

        while fast:
            if fast.next and fast.next.next:
                fast = fast.next.next
                slow = slow.next
            else:
                return None 
            
            if slow == fast:
                break
        
        slow = pHead
        while slow:
            if slow == fast:
                return slow
            slow = slow.next
            fast = fast.next
        return None
8. BM8 链表中倒数最后k个结点

双指针

class Solution:
    def FindKthToTail(self , pHead: ListNode, k: int) -> ListNode:
        # write code here
        if not pHead:
            return None 
        
        cur = pHead
        length = 0
        while cur:
            cur = cur.next
            length += 1

        if length < k:
            return None 
        
        slow, fast = pHead, pHead
        for i in range(k):
            fast = fast.next

        while(fast):
            fast = fast.next
            slow = slow.next 
        
        return slow 
9. BM9 删除链表的倒数第n个节点

逻辑上,倒数第k个节点和倒数第n个节点没啥差别,但一个是第k,另一个是k+1的逻辑

class Solution:
    def removeNthFromEnd(self , head: ListNode, n: int) -> ListNode:
        # write code here
                
        res = ListNode(-1)
        res.next = head

        slow, fast = res, res 

        while n:
            if fast and fast.next:
                fast = fast.next
            else:
                return None 
            n -= 1

        while fast.next:
            fast = fast.next
            slow = slow.next
        slow.next = slow.next.next
        
        return res.next
10. BM10 两个链表的第一个公共结点

考虑一下,有公共节点就是公共节点,没有就是空,每个节点走完一遍链表

class Solution:
    def FindFirstCommonNode(self , pHead1 , pHead2 ):
        # write code here

        cur1, cur2 = pHead1, pHead2

        while cur1 != cur2:
            cur1 = pHead2 if not cur1 else cur1.next
            cur2 = pHead1 if not cur2 else cur2.next

        return cur1
11. BM11 链表相加(二)
class Solution:
    def addInList(self , head1: ListNode, head2: ListNode) -> ListNode:
        # write code here
        # 栈
        if not head1:
            return head2
        if not head2:
            return head1

        s1 = []
        s2 = []
        while head1:
            s1.append(head1)
            head1 = head1.next
        while head2:
            s2.append(head2)
            head2 = head2.next

        res = ListNode(-1)
        num = 0
        while(len(s1) and len(s2)):
            num1 = s1.pop().val
            num2 = s2.pop().val
            num = num + num1 + num2  
            t = ListNode(num%10)
            t.next = res.next 
            res.next = t 
            num = num//10 
        
        while(len(s1)):
            num1 = s1.pop().val 
            num = num + num1 
            t = ListNode(num%10)
            t.next = res.next 
            res.next = t 
            num = num//10 

        while(len(s2)):
            num2 = s2.pop().val 
            num = num + num2 
            t = ListNode(num%10)
            t.next = res.next 
            res.next = t 
            num = num//10 
        
        if num > 0:
            t = ListNode(num)
            t.next = res.next 
            res.next = t 
        
        return res.next 
12. BM12 单链表的排序
class Solution:
    def sortInList(self , head: ListNode) -> ListNode:
        # write code here
        # 递归终止条件
        if(not head or not head.next):
            return head 
        
        # 归并排序中点
        fast = head.next
        slow = head 
        while (fast and fast.next):
            slow = slow.next
            fast = fast.next.next
        # 从中间截断链表
        tmp = slow.next
        slow.next = None 

        left = self.sortInList(head)
        right = self.sortInList(tmp)

        # 链表合并
        res = ListNode(-1)
        cur = res 
        while left and right:
            if left.val > right.val:
                cur.next = right
                right = right.next
            else:
                cur.next = left
                left = left.next
            cur = cur.next
        # 处理尾链
        cur.next = left if left else right
        return res.next
13. BM13 判断一个链表是否为回文结构
class Solution:
    def isPail(self , head: ListNode) -> bool:
        # write code here
        if not head or not head.next:
            return True 

        # 快慢指针找链表中点
        slow = head 
        fast = head.next

        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
        tmp = slow

        # 逆序后半部分链表
        cur = tmp.next
        tmp.next = None
        while cur:
            t = cur.next
            cur.next = tmp.next
            tmp.next = cur 
            cur = t 
        tmp = tmp.next 

        while(tmp and head):
            print(tmp.val, head.val)
            if (tmp.val != head.val):
                return False
            tmp = tmp.next
            head = head.next
        return True 

14. BM14 链表的奇偶重排
class Solution:
    def oddEvenList(self , head: ListNode) -> ListNode:
        # write code here
        if not head or not head.next:
            return head 

        h1 = ListNode(-1)
        cur = head

        p1 = ListNode(-1)
        p2 = h1

        while cur:
            p1.next = cur 
            p1 = p1.next
            cur = cur.next
            if not cur:
                p2.next = None
                break 
            p2.next = cur 
            p2 = p2.next
            cur = cur.next 

        p1.next = h1.next

        return head 
15. BM15 删除有序链表中重复的元素-I
class Solution:
    def deleteDuplicates(self , head: ListNode) -> ListNode:
        # write code here
        if not head or not head.next:
            return head 

        res = ListNode(-1)
        res.next = head 
        while head and head.next:
            while head.next and head.val == head.next.val:
                head.next = head.next.next
            head = head.next
        return res.next 
16. BM16 删除有序链表中重复的元素-II
class Solution:
    def deleteDuplicates(self , head: ListNode) -> ListNode:
        # write code here
        if not head or not head.next:
            return head 

        res = ListNode(-1)
        pre = res  

        flag = False
        while head:
            while head.next and head.val == head.next.val:
                head.next = head.next.next
                flag = True 

            if not flag:
                pre.next = head 
                pre = pre.next
                head = head.next
                pre.next = None 
            else:
                head = head.next
            flag = False 
        
        return res.next
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值