二进制链表转整数

标签: 链表 数学

难度: Easy

给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。

请你返回该链表所表示数字的 十进制值

示例 1:

输入:head = [1,0,1]
输出:5
解释:二进制数 (101) 转化为十进制数 (5)

示例 2:

输入:head = [0]
输出:0

示例 3:

输入:head = [1]
输出:1

示例 4:

输入:head = [1,0,0,1,0,0,1,1,1,0,0,0,0,0,0]
输出:18880

示例 5:

输入:head = [0,0]
输出:0

提示:

  • 链表不为空。
  • 链表的结点总数不超过 30
  • 每个结点的值不是 0 就是 1

Submission

运行时间: 28 ms

内存: 14.9 MB

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def getDecimalValue(self, head: ListNode) -> int:
        ans = 0
        while head:
            ans = ans * 2 + head.val
            head = head.next
        return ans

Explain

题解使用了一个单遍扫描链表的方法来直接将链表中的二进制数转换为十进制数。整个过程中,题解维护了一个变量 ans,初始值为 0。每遍历到链表的一个节点,就将当前 ans 值左移一位(即乘以 2),然后加上当前节点的值(0 或 1)。这样,当遍历完整个链表后,ans 中存储的就是链表所表示的二进制数对应的十进制值。

时间复杂度: O(n)

空间复杂度: O(1)

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def getDecimalValue(self, head: ListNode) -> int:
        ans = 0  # Initialize ans to zero, to hold the decimal value
        while head:  # Traverse each node in the linked list
            ans = ans * 2 + head.val  # Shift left (multiply by 2) and add current node's value
            head = head.next  # Move to the next node
        return ans  # Return the computed decimal value

Explore

题解中并未直接在代码中进行验证每个节点的值是否为0或1。通常在这类问题中,假设输入链表已经符合题目要求。如果需要增加这样的验证,可以在遍历链表的同时,检查节点的值是否为0或1。如果不符合,可以抛出异常或返回特定的错误值。

题解中没有明确处理链表为空的情况。但是,如果链表为空,由于`ans`初始化为0,并且遍历不会开始,函数将直接返回0。这在许多情况下是合理的,因为一个空的链表可以被视为代表数字0。

在二进制数中,每往左一位,数值就乘以2。因此,每当通过`ans = ans * 2`左移现有的数值时,就相当于为下一个二进制位腾出空间。然后通过加上当前节点的值(0或1),可以将当前位的值加入到正确的位置。这样,随着链表的逐个节点遍历,二进制数就被正确地从左到右构造出来。

确实,如果链表非常长,可能会导致整数溢出的问题,尤其是在固定大小的整型变量(如32位或64位整型)中。有几种方法可以处理这个问题:1. 使用支持更大整数或无限精度的数据类型,如Python中的int类型。2. 在每次操作后对一个特定的数进行模运算,以保持数字大小在安全范围内。3. 如果环境支持,可以使用库或数据类型特别设计来处理大数。