面试中会出现的典型链表类考题

对应思维导图讲解和下面代码一起看

在这里插入图片描述

反转单向链表

class Link_node():
    def __init__(self, value = None):
        self.value = value
        self.next = None
def build_linkList(List):
    for i in range(len(List)):
        List[i] = Link_node(List[i])
    for i in range(len(List)-1):
        List[i].next = List[i+1]
    return List[0], List[len(List)-1]
def reverse_one_directional_linkList(head):
    if head is None or head.next is None:
        return head
    
    newHead = Link_node()
    newHead.next = head
    
    p1 = newHead
    p2 = newHead.next
    temp = p2
    while temp is not None:
        temp = temp.next
        p2.next = p1
        p1 = p2
        p2 = temp
    head.next = None
    head = p1
    return head
        
    
head = build_linkList([1, 2, 3, 4])
head = reverse_one_directional_linkList(head)
p = head
while p is not None:
    print(p.value) 
    p = p.next
4
3
2
1

打印两个有序链表的公共部分

  • 给定两个有序链表头指针head1和head2,打印公共
  • 要求:两链表长度之和是N,则时间复杂度是O(N),额外空间要求O(1)
head1 = build_linkList([1, 2, 2, 5, 9, 10])
head2 = build_linkList([2, 2, 4, 5, 5, 8, 10])
def print_orderedLinklist_communalPart(head1, head2):
    p1 = head1
    p2 = head2
    res = []
    while p1 is not None and p2 is not None: 
        if p1.value < p2.value:
            p1 = p1.next
        elif p1.value > p2.value:
            p2 = p2.next
        else:
            res.append(p1.value)
            p1 = p1.next
            p2 = p2.next
    return res
print_orderedLinklist_communalPart(head1, head2)
[2, 2, 5, 10]

判断回文串

def IsPalindrome(head):
    if head.next is None:
        return True
    slow = head
    fast = head.next
    while fast.next is not None and fast.next.next is not None:
        slow = slow.next
        fast = fast.next.next
    if fast.next is not None:
        slow = slow.next
        fast = fast.next
        
    new = reverse_one_directional_linkList(slow.next)L
    p1 = head
    p2 = new
    while p2 is not None:
        if p2.value != p1.value:
            return False
        p2 = p2.next
        p1 = p1.next
        
    slow.next = reverse_one_directional_linkList(new)
    return True
head = build_linkList([1, 2])
IsPalindrome(head)
False

将单链表转化为:左边全部小于某个pivot,中间等于,右边大于的链表

def Linklist_for_partition(head, pivot):
    LL, LR, EL, ER, HL, HR = None, None, None, None, None, None
    p = head
    while p is not None:
        Next = p.next
        p.next = None
        if p.value < pivot:
            if LL is None:
                LL = p
                LR = p
            else:
                LR.next = p
                LR = LR.next   
        elif p.value > pivot:
            if HL is None:
                HL = p
                HR = p
            else:
                HR.next = p
                HR = HR.next
        else:
            if EL is None:
                EL = p
                ER = p
            else:
                ER.next = p
                ER = ER.next
                
        p = Next
    # 背就行了    
    if LR is not None:
        LR.next = EL
        ER = ER if ER is not None else LR
    if ER is not None:
        ER.next = HL
    
    return LL if LL is not None else EL if EL is not None else HL
head = build_linkList([4, 4, 3, 4])
List = Linklist_for_partition(head, 4)
while List is not None:
    print(List.value)
    List = List.next
3
4
4
4

有环链表判断入环节点

def IsLoopLinklist(head):
    if head is None or head.next is None or head.next.next is None:
        return False
    f = head.next.next
    s = head.next
    while f != s:
        if f.next is None and f.next.next is None:
            return False
        f = f.next.next
        s = s.next
    f = head
    while f != s:
        f = f.next
        s = s.next
    return s
head, tail = build_linkList([1, 2, 3, 4, 5, 1, 2, 3, 4])
tail.next = head.next.next.next.next.next
tail.next = head.next.next.next.next.next
IsLoopLinklist(head).value
1

寻找两个链表的交叉部分

head1, _ = build_linkList([1, 2, 3, 4, 5])
head2, tail2 = build_linkList([6, 7, 8])
tail2.next = head1.next.next
def Two_NoneLoop_Linklist(head1, head2):
    p = head2
    while p.next is not None:
        p = p.next
    temp = p
    p.next = head2 
    common = IsLoopLinklist(head1)
    temp.next = None
    return common
def Two_AllLoop_Linklist(head1, head2, loop1, loop2):
    p1 = head1
    p2 = head2
    if loop1 is loop2:
        n1 = 1
        n2 = 1
        while p1 is not loop1:
            n1 += 1
            p1 = p1.next
        while p2 is not loop2:
            n2 += 1
            p2 = p2.next
        
        n = abs(n1-n2)
        cur = head1 if n1>n2 else head2
        p = head1 if cur is not head1 else head2
        
        while n > 0:
            cur = cur.next
            n -= 1
        while p is not cur:
            p = p.next
            cur = cur.next
        return cur
    
    else:
        cur = loop1.next
        while cur is not loop1:
            if cur is loop2:
                return loop2
            cur = cur.next
        return False
    
def Find_CommonPart_InTwo_Linklist(head1, head2):
    loop1 = IsLoopLinklist(head1)
    loop2 = IsLoopLinklist(head2)
    
    if loop1 is False and loop2 is False:
        return Two_NoneLoop_Linklist(head1, head2)
    elif loop1 is not False and loop2 is not False:
        return Two_AllLoop_Linklist(head1, head2, loop1, loop2)
    else:
        return False
head1, tail1 = build_linkList([1, 2, 3, 4, 5, 1, 2, 3, 4])
tail1.next = head1.next.next.next.next.next
head2, tail2 = build_linkList([6, 7, 8])
tail2.next = head1.next
Find_CommonPart_InTwo_Linklist(head1, head2).value
2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值