leetcode刷题之链表专题

文章目录

  • 1.链表的操作
    • 1.1 删除链表的倒数第N个节点
    • 1.2 合并两个有序链表
    • 1.3 合并K个排序链表
    • 1.4 两两交换链表中的节点
    • 1.5 K个一组翻转链表
    • 1.6 旋转链表
    • 1.7 删除排序链表中的重复元素II
    • 1.8 删除排序链表中的重复元素
    • 1.9 分隔链表
    • 1.10 反转链表II
    • 1.11 重排链表
    • 1.12 对链表进行插入排序
    • 1.13 排序链表
    • 1.14 相交链表
    • 1.15 移除链表元素
    • 1.16 反转链表
    • 1.17 回文链表
    • 1.18 删除链表中的节点
    • 1.19 分隔链表
    • 1.20 链表中的下一个更大节点
    • 1.21 从链表中删去总和值为零的连续节点
    • 1.22 二进制链表转整数
  • 2. 链表的应用
    • 2.1 两数相加
    • 2.2 有序链表转换二叉搜索树
    • 2.3 复制带随机指针的链表
    • 2.4 环形链表
    • 2.5 环形链表II
    • 2.6 奇偶链表
    • 2.7 两数相加II
    • 2.8 链表组件
    • 2.9 设计链表
    • 2.10 链表的中间节点

1.链表的操作

1.1 删除链表的倒数第N个节点

leetcode刷题之链表专题_第1张图片

def removeNthFromEnd(self, head: ListNode, n: int) :
        a = head
        b = head
        
        for i in range(n):
            if a.next:
                a = a.next
            else:
                return head.next
                
        while a.next:
            a = a.next
            b = b.next
        b.next = b.next.next
        return head

1.2 合并两个有序链表

leetcode刷题之链表专题_第2张图片

def mergeTwoLists(self, l1: ListNode, l2: ListNode):
        res=ListNode(None)
        node=res
        while l1 and l2:
            if l1.val<l2.val:
                node.next,l1=l1,l1.next
            else:
                node.next,l2=l2,l2.next
            node=node.next
        if l1:
            node.next=l1
        else:
            node.next=l2
        return res.next

1.3 合并K个排序链表

leetcode刷题之链表专题_第3张图片

class Solution:
    def mergeKLists(self, lists: List[ListNode]):
        if not lists:return 
        n = len(lists)
        return self.merge(lists, 0, n-1)
    def merge(self,lists, left, right):
        if left == right:
            return lists[left]
        mid = left + (right - left) // 2
        l1 = self.merge(lists, left, mid)
        l2 = self.merge(lists, mid+1, right)
        return self.mergeTwoLists(l1, l2)
    def mergeTwoLists(self,l1, l2):
        if not l1:return l2
        if not l2:return l1
        if l1.val < l2.val:
            l1.next = self.mergeTwoLists(l1.next, l2)
            return l1
        else:
            l2.next = self.mergeTwoLists(l1, l2.next)
            return l2

1.4 两两交换链表中的节点

leetcode刷题之链表专题_第4张图片

def swapPairs(self, head: ListNode):
        if not head or not head.next:
            return head
        l1=head
        l2=head.next
        l1.next=self.swapPairs(l2.next)
        l2.next=l1
        return l2

1.5 K个一组翻转链表

leetcode刷题之链表专题_第5张图片

def reverseKGroup(self, head: ListNode, k: int):
        dummy = ListNode(0)
        p = dummy
        while True:
            count = k 
            stack = []
            tmp = head
            while count and tmp:
                stack.append(tmp)
                tmp = tmp.next
                count -= 1
            # 注意,目前tmp所在k+1位置
            # 说明剩下的链表不够k个,跳出循环
            if count : 
                p.next = head
                break
            # 翻转操作
            while stack:
                p.next = stack.pop()
                p = p.next
            #与剩下链表连接起来 
            p.next = tmp
            head = tmp
        
        return dummy.next

1.6 旋转链表

leetcode刷题之链表专题_第6张图片

def rotateRight(self, head: ListNode, k: int) :
        if head is None or head.next is None: return head
        start, end, len = head, None, 0
        while head:
            end = head
            head = head.next
            len += 1
        end.next = start
        pos = len - k % len
        while pos > 1:
            start = start.next
            pos -= 1
        ret = start.next
        start.next = None
        return ret

1.7 删除排序链表中的重复元素II

leetcode刷题之链表专题_第7张图片

def deleteDuplicates(self, head: ListNode) :
        thead = ListNode('a')
        thead.next = head
        pre,cur = None,thead
        while cur:
            pre=cur
            cur=cur.next
            while cur and cur.next and cur.next.val == cur.val:
                t=cur.val
                while cur and cur.val==t:
                    cur=cur.next
                pre.next=cur
        return thead.next

1.8 删除排序链表中的重复元素

leetcode刷题之链表专题_第8张图片

 def deleteDuplicates(self, head: ListNode) :
        ans=head
        while head!=None:
            if head.next!=None and head.next.val==head.val:
                head.next=head.next.next
            else:
                head=head.next
        return ans

1.9 分隔链表

leetcode刷题之链表专题_第9张图片

def partition(self, head: ListNode, x: int) :
        dummy1 = ListNode(-1)
        dummy2 = ListNode(-1)
        p1 = dummy1
        p2 = dummy2
        while head:
            if head.val < x:
                p1.next = head
                p1 = p1.next
            else:
                p2.next = head
                p2 = p2.next
            head = head.next
        # print(listNodeToString(dummy1.next))
        # print(listNodeToString(dummy2.next))
        p1.next = dummy2.next
        p2.next = None
        return dummy1.next

1.10 反转链表II

leetcode刷题之链表专题_第10张图片

def reverseBetween(self, head: ListNode, m: int, n: int) :
        dummy = ListNode(-1)
        dummy.next = head
        pre = dummy
        # 找到翻转链表部分的前一个节点, 1->2->3->4->5->NULL, m = 2, n = 4 指的是 节点值为1
        for _ in range(m-1):
            pre = pre.next
        # 用双指针,进行链表翻转
        node = None
        cur = pre.next
        for _ in range(n-m+1):
            tmp = cur.next
            cur.next = node
            node = cur
            cur = tmp
        # 将翻转部分 和 原链表拼接
        pre.next.next = cur
        pre.next = node
        return dummy.next

1.11 重排链表

leetcode刷题之链表专题_第11张图片

def reorderList(self, head: ListNode) -> None:
        if not head or not head.next:
            return head
        cur = head
        stack = []
        while cur:
            stack.append(cur)
            cur = cur.next
        cur = stack.pop(0)
        while stack:
            cur.next = stack.pop()
            cur = cur.next
            if stack:
                cur.next = stack.pop(0)
                cur=cur.next
        cur.next = None

1.12 对链表进行插入排序

leetcode刷题之链表专题_第12张图片

def insertionSortList(self, head: ListNode) :
        if not head or not head.next:
            return head       
        dummy = ListNode(-1)
        dummy.next = head
        pre = head #pre始终指着排序好链表的最后一个节点
        cur = head.next #cur始终指着未排序链表的第一个节点
        while cur:
            tail = cur.next
            pre.next = tail  #把cur这个节点拿出来        
            p = dummy
            while p.next and p.next.val < cur.val: #找到插入的位置
                p = p.next            
            cur.next = p.next #把cur插入到p和p.next之间
            p.next = cur
            cur = tail   
            if p == pre:#如果刚插入到了已排序链表的末尾
                pre = pre.next #那么就更新pre
        return dummy.next

1.13 排序链表

leetcode刷题之链表专题_第13张图片

def sortList(self, head: ListNode) :
        if head is None:
            return None
        val_list = []
        while head:
            val_list.append(head.val)
            head = head.next
        val_list.sort()
        # 逆序建立链表
        ptr = ListNode(val_list.pop())
        while len(val_list)!=0:
            x = val_list.pop()
            new_node = ListNode(x)
            new_node.next = ptr
            ptr = new_node
        return ptr

1.14 相交链表

leetcode刷题之链表专题_第14张图片

def getIntersectionNode(self, headA: ListNode, headB: ListNode) :
        p,q=headA,headB
        while p!=q:
            p=p.next if p else headB
            q=q.next if q else headA
        return p

1.15 移除链表元素

leetcode刷题之链表专题_第15张图片

def removeElements(self, head: ListNode, val: int) :
        while head != None and val == head.val:
            head=head.next
        if head==None:
            return None
        else:
            node = head
            while node.next!=None:
                if node.next.val==val:
                    node.next = node.next.next
                else:
                    node=node.next
            return head

1.16 反转链表

leetcode刷题之链表专题_第16张图片

def reverseList(self, head: ListNode) :
        '''
        p,rev=head,None
        while p:
            rev,rev.next,p=p,rev,p.next
        return rev
        '''
        if not head or not head.next:
            return head
        pre=None
        while head:
            tmp=head.next
            head.next=pre
            pre=head
            head=tmp
        return pre

1.17 回文链表

leetcode刷题之链表专题_第17张图片

def isPalindrome(self, head: ListNode) :
        s1=0
        s2=0
        t=1
        while head!=None:
            s1=s1*10+head.val
            s2=s2+t*head.val
            t=t*10
            head=head.next
        return s1==s2

1.18 删除链表中的节点

leetcode刷题之链表专题_第18张图片

def deleteNode(self, node):
        """
        :type node: ListNode
        :rtype: void Do not return anything, modify node in-place instead.
        """
        node.val=node.next.val
        node.next=node.next.next

1.19 分隔链表

leetcode刷题之链表专题_第19张图片

def splitListToParts(self, root: ListNode, k: int) :
        cur = root 
        l = 0
        res = []
        while cur:
            l += 1
            cur = cur.next
        avg = l //k
        ext = l % k
        for i in range(k):
            res.append(root)
            if root:  #要判断下
                for j in range(1,avg + (i < ext)):
                    root = root.next
                nxt = root.next
                root.next = None
                root = nxt
        return res

1.20 链表中的下一个更大节点

leetcode刷题之链表专题_第20张图片

def nextLargerNodes(self, head: ListNode) :
        if not head:
            return []
        nums = []
        cur = head
        while cur:
            nums.append(cur.val)
            cur=cur.next
        stack = [0]
        res = [0]*len(nums)
        for i in range(1,len(nums)):
            while stack and nums[i]>nums[stack[-1]]:
                res[stack[-1]]=nums[i]
                stack.pop()
            stack.append(i)
        return res

1.21 从链表中删去总和值为零的连续节点

leetcode刷题之链表专题_第21张图片

def removeZeroSumSublists(self, head: ListNode) :
        A=[]
        while head:
            A.append(head.val)
            head=head.next
        A=[0]+A
        seen={
     }
        seen[0]=0
        prefix=0
        for i,value in enumerate(A):
            prefix+=value
            seen[prefix]=i
        ans=[]
        prefix=0
        i=0
        while True:
            prefix+=A[i]
            if seen[prefix]+1>=len(A):
                break
            ans.append(A[seen[prefix]+1])
            i=seen[prefix]+1
        re=ListNode(0)
        r=re
        for i in range(len(ans)):
            r.next=ListNode(ans[i])
            r=r.next
        return re.next

1.22 二进制链表转整数

leetcode刷题之链表专题_第22张图片

def getDecimalValue(self, head: ListNode) :
        res=0
        while head:
            res=res*2+head.val
            head=head.next
        return res

2. 链表的应用

2.1 两数相加

leetcode刷题之链表专题_第23张图片

def addTwoNumbers(self, l1: ListNode, l2: ListNode) :
        re=ListNode(0)
        r=re
        carry=0
        while l1 or l2:
            x=l1.val if l1 else 0
            y=l2.val if l2 else 0
            s=x+y+carry
            carry=s//10
            r.next=ListNode(s%10)
            r=r.next
            if l1:
                l1=l1.next
            if l2:
                l2=l2.next
        if carry>0:
            r.next=ListNode(1)
        return re.next

2.2 有序链表转换二叉搜索树

leetcode刷题之链表专题_第24张图片

def sortedListToBST(self, head: ListNode) :
        if head==None:
            return None
        if head.next==None:
            return TreeNode(head.val)
        pre,slow,fast=head,head.next,head.next.next
        while fast!=None and fast.next!=None:
            pre,slow,fast=pre.next,slow.next,fast.next.next
        root=TreeNode(slow.val)
        pre.next=None
        
        root.left=self.sortedListToBST(head)
        root.right=self.sortedListToBST(slow.next)
        return root

2.3 复制带随机指针的链表

leetcode刷题之链表专题_第25张图片

def copyRandomList(self, head: 'Node') :
        def copyNode(node,res):
            if not node:
                return None
            if node in res:
                return res[node]
            copy=Node(node.val,None,None)
            res[node]=copy
            copy.next=copyNode(node.next,res)
            copy.random=copyNode(node.random,res)
            return copy
        return copyNode(head,{
     })

2.4 环形链表

leetcode刷题之链表专题_第26张图片

def hasCycle(self, head: ListNode) :
        if not head:
            return False
        while head.next and head.val != None:
            head.val = None  # 遍历的过程中将值置空
            head = head.next
        if not head.next:  # 如果碰到空发现已经结束,则无环
            return False
        return True  # 否则有环

2.5 环形链表II

leetcode刷题之链表专题_第27张图片

def detectCycle(self, head: ListNode) :
        if head and head.next:
            fast=head.next.next
            slow=head.next
        else:
            return None
        
        while fast:
            if fast!=slow:
                if fast.next:
                    fast=fast.next.next
                else:
                    return None
                slow=slow.next
            else:
                detection=head
                while detection!=slow:
                    slow=slow.next
                    detection=detection.next
                return detection

2.6 奇偶链表

leetcode刷题之链表专题_第28张图片

def oddEvenList(self, head: ListNode) :
        if not head or not head.next or not head.next.next:
            return head
        point1,point2=head,head.next
        p1,p2=point1,point2
        while p2!=None and p2.next:
            p1.next=p1.next.next
            p2.next=p2.next.next
            p1=p1.next
            p2=p2.next
        p1.next=point2
        return point1

2.7 两数相加II

leetcode刷题之链表专题_第29张图片

def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        num1 = ''
        num2 = ''
        while l1:
            num1 += str(l1.val)
            l1 = l1.next
        while l2:
            num2 += str(l2.val)
            l2 = l2.next
        add = str(int(num1) + int(num2))
        head = ListNode(add[0])
        answer = head
        for i in range(1, len(add)):
            node = ListNode(add[i])
            head.next = node
            head = head.next
        return answer

2.8 链表组件

leetcode刷题之链表专题_第30张图片

def numComponents(self, head: ListNode, G: List[int]) :
        Gset = set(G)
        cur = head
        ans = 0
        while cur:
            if (cur.val in Gset and
                    getattr(cur.next, 'val', None) not in Gset):
                ans += 1
            cur = cur.next
        return ans

2.9 设计链表

leetcode刷题之链表专题_第31张图片

class MyLinkedList:
    def __init__(self):
        self.linked_list=[]
    def get(self, index: int) :
        if 0<=index<=len(self.linked_list)-1:
            return self.linked_list[index]
        else:
            return -1
    def addAtHead(self, val: int) :
        self.linked_list.insert(0,val)   
    def addAtTail(self, val: int) :
        self.linked_list.append(val)
    def addAtIndex(self, index: int, val: int) :
        if index<=len(self.linked_list):
            self.linked_list.insert(index,val)
    def deleteAtIndex(self, index: int) :
        if 0<=index<=len(self.linked_list)-1:
            return self.linked_list.pop(index)

2.10 链表的中间节点

leetcode刷题之链表专题_第32张图片

def middleNode(self, head: ListNode) :
        slow=fast=head
        while fast and fast.next:
            slow=slow.next
            fast=fast.next.next
        return slow

你可能感兴趣的:(算法刷题VS面试刷题,leetcode)