中心对称数

Submission

运行时间: 18 ms

内存: 15.9 MB

class Solution:
    def isStrobogrammatic(self, num: str) -> bool:
        # 创建一个字典,用于存储中心对称的字符对
        strobo_dict = {'0': '0', '1': '1', '6': '9', '8': '8', '9': '6'}
        
        # 将输入字符串转换为列表,方便进行字符操作
        num_list = list(num)
        
        # 使用双指针法,从字符串两端向中间遍历
        left, right = 0, len(num) - 1
        while left < right:
            # 如果当前左右指针所指的字符不是中心对称的,则返回False
            if num_list[left] not in strobo_dict or num_list[right] not in strobo_dict or strobo_dict[num_list[left]] != num_list[right]:
                return False
            
            # 继续向中间移动左右指针
            left += 1
            right -= 1
        
        # 如果字符串长度为奇数,还需要判断中间的字符是否是中心对称的
        if left == right and num_list[left] not in ['0', '1', '8']:
            return False
        
        # 通过所有判断,返回True
        return True

solution = Solution()
print(solution.isStrobogrammatic("69"))  # 输出: True
print(solution.isStrobogrammatic("88"))  # 输出: True
print(solution.isStrobogrammatic("962"))  # 输出: False
print(solution.isStrobogrammatic("1"))  # 输出: True

Explain

该题解使用双指针法来判断一个数是否为中心对称数。首先创建一个字典 strobo_dict,用于存储中心对称的字符对。然后将输入字符串转换为列表,方便进行字符操作。使用双指针 left 和 right 分别指向字符串的两端,向中间移动。在移动过程中,判断 left 和 right 指向的字符是否在 strobo_dict 中,以及它们是否对称。如果不满足条件,则返回 False。如果字符串长度为奇数,还需要判断中间字符是否为 '0'、'1' 或 '8'。如果通过所有判断,则返回 True。

时间复杂度: O(n)

空间复杂度: O(n)

class Solution:
    def isStrobogrammatic(self, num: str) -> bool:
        # 创建一个字典,用于存储中心对称的字符对
        strobo_dict = {'0': '0', '1': '1', '6': '9', '8': '8', '9': '6'}
        
        # 将输入字符串转换为列表,方便进行字符操作
        num_list = list(num)
        
        # 使用双指针法,从字符串两端向中间遍历
        left, right = 0, len(num) - 1
        while left < right:
            # 如果当前左右指针所指的字符不是中心对称的,则返回False
            if num_list[left] not in strobo_dict or num_list[right] not in strobo_dict or strobo_dict[num_list[left]] != num_list[right]:
                return False
            
            # 继续向中间移动左右指针
            left += 1
            right -= 1
        
        # 如果字符串长度为奇数,还需要判断中间的字符是否是中心对称的
        if left == right and num_list[left] not in ['0', '1', '8']:
            return False
        
        # 通过所有判断,返回True
        return True

solution = Solution()
print(solution.isStrobogrammatic("69"))  # 输出: True
print(solution.isStrobogrammatic("88"))  # 输出: True
print(solution.isStrobogrammatic("962"))  # 输出: False
print(solution.isStrobogrammatic("1"))  # 输出: True

Explore

双指针法在这种场景中非常有效,因为它可以同时从字符串的两端向中心移动并对比字符。这种方法的时间复杂度为 O(n/2),即遍历一半字符串长度,这比逐个检查每个字符(单循环的 O(n) 时间复杂度)更高效。而递归方法虽然可行,但它通常涉及额外的内存开销用于递归调用栈,且在这个问题中并不提供额外的逻辑简化或性能优势。因此,双指针法既简洁又高效,特别适用于此类对称检查问题。

字典 strobo_dict 中的键值对是精心选择的,它们代表了那些在180度旋转后仍然能够表示同一数字或互为镜像的数字。这些键值对包括:'0': '0'(0旋转后仍为0),'1': '1'(1旋转后仍为1),'6': '9'(6旋转后成为9),'8': '8'(8旋转后仍为8),'9': '6'(9旋转后成为6)。没有遗漏或多余的元素,因为其他数字(如2、3、4、5、7)在旋转后无法形成有效的对称数字。

在字符串长度为奇数时,中间的字符在180度旋转后必须仍然显现为同一个字符,因此只能是那些旋转后能与自身相一致的数字。这些数字包括 '0'、'1' 和 '8'。这是因为这三个数字旋转180度后仍然保持不变,而其他数字要么变形(如6和9是互相旋转的),要么完全不是对称数字(如2、3、4、5、7)。这种设计确保了中心对称数的定义在任何长度的数字中都能被正确地验证。

在这种特定的问题设置中,如果任何一个字符对(即左右指针所指的字符)不符合中心对称的条件,那么整个字符串就不能被认定为中心对称数。因此,一旦发现不匹配的字符对,立即返回 False 是合理的,因为这意味着至少有一部分不满足中心对称的要求,无需进一步检查其余部分。这种方法是高效且符合逻辑的,确保了算法的正确性和性能。