如何把链表以k个结点为一组进行翻转

【MT笔试题】

题目描述:

K 链表翻转是指把每K个相邻的结点看成一组进行翻转,如果剩余结点不足 K 个,则保持不变。假设给定链表 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 和一个数K,如果K的值为2,那么翻转后的链表是:2 -> 1 -> 4 -> 3 -> 6 -> 5 -> 7,如果K是3,那么翻转后的链表为:3 -> 2 -> 1 -> 6 -> 5 -> 4 -> 7.

解法: 先把链表按照K长度切割,把每段都翻转,除了最后一段,然后再链接起来。


class k_reverse:
    def __init__(self):
        pass

    def __call__(self, link, k):
        return self.handle(link, k)

    @staticmethod
    def patition(link: SingleLink, k):  # 切分
        cur = link.head
        head = cur
        lst = []
        i = 0
        maybe_tail = None
        while cur:
            i += 1
            if i != k:  # 个数不够
                maybe_tail = cur
                cur = cur.next
                continue
            tmp = cur.next  # 个数够了
            cur.next = None
            tail = cur
            cur = tmp

            temp = SingleLink()
            temp.head = head
            temp.tail = tail
            lst.append(temp)

            head = tmp
            i = 0

        temp = SingleLink()
        if head:
            temp.head = head
        if maybe_tail:
            temp.tail = maybe_tail
        if temp.head:
            lst.append(temp)  # 最后一段不足k的头

        return lst

    @staticmethod
    def reverse(link: SingleLink):  # 翻转
        left = link.head
        if left is None and left.next is None:
            return

        # 至少两个结点
        right = left.next
        while right:
            tmp = right.next
            right.next = left
            if left is link.head:
                left.next = None
                link.tail = left
            left = right
            right = tmp
        link.head = left
	
	    def handle(self, link, k):
        part_lst = self.patition(link, k)
        for i in part_lst:
            if i == part_lst[-1]:
                break
            self.reverse(i)

        length = len(part_lst)
        if length:  # 不为空
            i = 0
            while i < length-1:
                part_lst[i].tail.next = part_lst[i+1].head
                i += 1
        ln = SingleLink()
        ln.head = part_lst[0].head
        ln.tail = part_lst[-1].tail
        return ln

测试:

instance = k_reverse()

print("反转前: ", end="")
p = ln.head
while p:
    print(p.data, end=" ")
    p = p.next

ln = instance(ln, 3)
print()
print("反转后: ", end="")
p = ln.head
while p:
    print(p.data, end=" ")
    p = p.next

print()
print("尾巴结点:", ln.tail.data)

反转前: 1 2 3 4 5 6 7 8 
反转后: 3 2 1 6 5 4 7 8 
尾巴结点: 8
posted @ 2019-10-30 21:10  段明  阅读(463)  评论(0编辑  收藏  举报