返回

轻松搞定链表翻转,破解字节面试“难题”

Android

在程序员的面试中,链表问题是一个常见且重要的考点。字节跳动作为一家顶尖科技公司,面试中自然少不了对链表的考察。今天,我们就来深入解析一道来自字节跳动的链表翻转面试题。

这道题要求面试者翻转一个链表,但加入了一个额外的条件:链表中可能包含一个环。环形链表的翻转相对于普通链表难度更高,增加了问题的复杂度。

算法详解

解决环形链表翻转问题,需要分步进行:

1. 判断是否存在环

使用快慢指针法判断链表中是否存在环。快指针每次走两步,慢指针每次走一步。如果快指针追上了慢指针,则链表存在环。

2. 找到环的入口

如果链表存在环,则快指针和慢指针会在环内相遇。此时,慢指针继续走,快指针从链表头部重新开始走,每次一步。当快指针和慢指针再次相遇时,相遇点就是环的入口。

3. 翻转链表

找到环的入口后,从入口处开始翻转链表。使用三个指针:prev、curr和next。prev指向翻转前的结点,curr指向当前结点,next指向翻转后的结点。

不断将curr结点指向prev,然后将prev和curr后移,直到curr为null。这样,链表就翻转完成了。

4. 处理环形部分

如果链表存在环,还需要处理环形部分。从环的入口开始,将curr指向next,然后将next指向prev,直到curr为null。这样,环形部分也翻转完成了。

示例代码

def reverse_linked_list_with_cycle(head):
  # 判断是否存在环
  slow = head
  fast = head
  while fast and fast.next:
    slow = slow.next
    fast = fast.next.next
    if slow == fast:
      return True

  # 找到环的入口
  slow = head
  while slow != fast:
    slow = slow.next
    fast = fast.next.next

  # 翻转链表
  prev = None
  curr = head
  next = None
  while curr:
    next = curr.next
    curr.next = prev
    prev = curr
    curr = next

  # 处理环形部分
  curr = slow
  next = None
  while curr:
    next = curr.next
    curr.next = prev
    prev = curr
    curr = next

  return head

总结

这道字节跳动面试题考察了链表翻转以及环形链表处理的知识点。通过深入理解算法原理和示例代码,面试者可以提高对链表问题的解决能力,为面试做好充分的准备。