返回

剑指快乐数、删除排序链表中的重复元素 II、K 个一组翻转链表、分隔链表的解法

前端

202. 快乐数

快乐数是指一个正整数,如果对其反复进行以下操作,最终会变为 1:

  • 将其各位数字的平方和计算出来。
  • 将平方和再次分解成个位数并计算其平方和。
  • 重复以上步骤,直到得到的数为 1。

例如,19 是一个快乐数,因为 1^2 + 9^2 = 82,8^2 + 2^2 = 68,6^2 + 8^2 = 100,1^2 + 0^2 + 0^2 = 1。

解题思路:

将快乐数问题转换为链表是否有环的问题。如果链表有环,说明不是快乐数;如果链表等于 1,说明是快乐数。

def isHappy(n):
  # 存储已经访问过的数字
  visited = set()

  while n != 1:
    # 如果数字已经访问过,说明有环,不是快乐数
    if n in visited:
      return False

    # 将数字加入 visited 集合
    visited.add(n)

    # 计算数字各位数字的平方和
    n = sum(int(i)**2 for i in str(n))

  return True

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

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

解题思路:

使用双指针,precur,判断 pre.next 是否等于 cur,如果是,则删除 cur

def deleteDuplicates(head):
  # 如果链表为空或只有一个元素,直接返回
  if not head or not head.next:
    return head

  # 初始化 pre 和 cur 指针
  pre = head
  cur = head.next

  # 遍历链表
  while cur:
    # 如果 pre 和 cur 的值相同,则删除 cur
    if pre.val == cur.val:
      pre.next = cur.next
    # 否则,pre 指针后移
    else:
      pre = cur

    # cur 指针后移
    cur = cur.next

  return head

25. K 个一组翻转链表

给定一个链表,每 K 个节点一组进行翻转,并返回翻转后的链表。

解题思路:

使用三个指针,precurnext,将链表分成三部分:pre 指针指向当前组的最后一个节点,cur 指针指向当前组的第一个节点,next 指针指向当前组的下一个节点。然后,将 cur 指针指向 pre 指针,将 next 指针指向 cur 指针,并将 pre 指针指向 cur 指针。重复此过程,直到链表翻转完成。

def reverseKGroup(head, k):
  # 如果链表为空或只有一个元素,直接返回
  if not head or not head.next:
    return head

  # 初始化 pre、cur 和 next 指针
  pre = None
  cur = head
  next = head.next

  # 遍历链表
  while cur:
    # 如果当前组的长度小于 k,则直接返回
    if len(cur) < k:
      return head

    # 翻转当前组
    for _ in range(k-1):
      next = cur.next
      cur.next = pre
      pre = cur
      cur = next

    # 将当前组的最后一个节点连接到下一组的第一个节点
    next = cur.next
    cur.next = pre
    pre = cur
    cur = next

  return head

86. 分隔链表

给定一个链表和一个值 x,将链表分为两部分:所有小于 x 的节点组成一个链表,所有大于或等于 x 的节点组成另一个链表。

解题思路:

使用两个指针,head1head2,分别指向小于 x 的链表和大于或等于 x 的链表。然后,遍历链表,将小于 x 的节点连接到 head1 指针,将大于或等于 x 的节点连接到 head2 指针。最后,将 head1 指针和 head2 指针连接起来,形成最终的链表。

def partition(head, x):
  # 初始化 head1 和 head2 指针
  head1 = ListNode(0)
  head2 = ListNode(0)

  # 初始化 cur1 和 cur2 指针
  cur1 = head1
  cur2 = head2

  # 遍历链表
  while head:
    # 如果当前节点的值小于 x,则连接到 head1 指针
    if head.val < x:
      cur1.next = head
      cur1 = cur1.next
    # 否则,连接到 head2 指针
    else:
      cur2.next = head
      cur2 = cur2.next

    # 移动 head 指针
    head = head.next

  # 将 head1 指针和 head2 指针连接起来
  cur1.next = head2.next
  cur2.next = None

  return head1.next