返回

LeetCode刷题记录-693:交替位二进制数

前端

前言

在浩瀚的LeetCode题海中,我将带领大家共同攻克693题:交替位二进制数。乍看之下,这道题看似容易,甚至可以玩些小聪明。然而,真正的奥秘却隐藏在位运算的玄机之中。让我们踏上探索的征程,深入领略位运算的魅力。

题目解析

给定一个正整数n,求满足以下条件的正整数m的个数:

  • mn的子集(即m的二进制表示中,1的位置在n的二进制表示中也为1)。
  • m的二进制表示中,相邻的两个1之间至少有一个0

例如,当n=5时,满足条件的m有:

  • 1 (00001)
  • 3 (00011)
  • 5 (00101)
  • 6 (00110)
  • 7 (00111)
  • 9 (01001)
  • 11 (01011)
  • 12 (01100)
  • 13 (01101)
  • 14 (01110)

因此,答案为10

思路分析

要解决这个问题,我们可以采用递归的方法。对于给定的n,我们可以枚举其所有可能的子集m。对于每个子集m,我们可以检查它是否满足交替位二进制数的条件。如果满足,则答案加1

具体地,我们可以将n的二进制表示视为一个长度为32的数组bits,其中bits[i]表示第i位是否为1。对于每个子集m,我们可以将其二进制表示视为另一个长度为32的数组sub_bits,其中sub_bits[i]表示第i位是否为1

为了检查m是否满足交替位二进制数的条件,我们可以遍历sub_bits数组。对于每个i,如果sub_bits[i]sub_bits[i+1]都为1,则m不满足条件。

如果m满足条件,则答案加1。最后,返回答案。

代码实现

def count_alternating_bits(n):
  """
  计算满足条件的子集数量。

  Args:
    n: 给定的正整数。

  Returns:
    满足条件的子集数量。
  """

  # 将n的二进制表示转换为数组
  bits = []
  while n > 0:
    bits.append(n % 2)
    n //= 2

  # 初始化答案为0
  count = 0

  # 枚举所有可能的子集
  for i in range(1 << len(bits)):
    # 将子集的二进制表示转换为数组
    sub_bits = []
    for j in range(len(bits)):
      if (i >> j) & 1:
        sub_bits.append(bits[j])

    # 检查子集是否满足条件
    is_valid = True
    for j in range(len(sub_bits) - 1):
      if sub_bits[j] == sub_bits[j + 1] == 1:
        is_valid = False
        break

    # 如果子集满足条件,则答案加1
    if is_valid:
      count += 1

  return count

位运算的应用

在这道题中,位运算发挥着至关重要的作用。具体来说,我们使用位运算来:

  • 将整数的二进制表示转换为数组
  • 检查两个二进制位是否相等
  • 检查子集是否满足交替位二进制数的条件

位运算的这些应用极大地简化了问题的求解过程。

扩展与总结

交替位二进制数的问题不仅是一道LeetCode题目,更是一个理解位运算原理的绝佳案例。通过这道题,我们掌握了位运算的基本操作,并体会到了位运算在解决问题中的强大威力。

在未来的编程实践中,我们应该灵活运用位运算,不断探索其在不同场景中的应用。通过不断地学习和实践,我们终将成为位运算的熟练使用者,在解决复杂问题时游刃有余。