相似 RGB 颜色

Submission

运行时间: 32 ms

内存: 16.0 MB

class Solution:
    def similarRGB(self, color: str) -> str:
        mp={'a':10,'b':11,'c':12,'d':13,'e':14,'f':15}
        color=color[1:]
        arr=[color[:2],color[2:4],color[4:6]]
        for i in range(3):
            a,b=arr[i][0],arr[i][1]
            cur=0
            if a.isdigit():
                cur+=int(a)*16
            else:
                cur+=mp[a]*16
            if b.isdigit():
                cur+=int(b)
            else:
                cur+=mp[b]
            arr[i]=cur
        ans=[]
        for i in range(3):
            pre,idx=inf,0
            for j in range(16):
                if abs(arr[i]-j*17)<pre:
                    pre=abs(arr[i]-j*17)
                    idx=j
            ch=str(idx)
            if idx>=10:
                ch=chr(idx-10+97)
            ans.append(ch*2)
        return "#"+"".join(ans)

Explain

这个题解的思路是将 RGB 颜色转换为整数表示,然后对每个分量 R、G、B 分别进行处理。对于每个分量,找到与其最接近的 17 的倍数(即 0x11、0x22、...、0xff),最后将找到的三个分量值重新组合成一个新的 RGB 颜色。具体做法是先将 16 进制字符转换为对应的整数值,然后遍历 0 到 15,找到差值最小的数字,将其转换为 16 进制字符作为结果。

时间复杂度: O(1)

空间复杂度: O(1)

class Solution:
    def similarRGB(self, color: str) -> str:
        # 16进制字符到整数的映射
        mp={'a':10,'b':11,'c':12,'d':13,'e':14,'f':15}
        # 去掉'#',得到RGB颜色的三个分量 
        color=color[1:]
        arr=[color[:2],color[2:4],color[4:6]]
        # 处理每个分量
        for i in range(3):
            a,b=arr[i][0],arr[i][1]
            cur=0
            # 将16进制转为整数
            if a.isdigit():
                cur+=int(a)*16
            else:
                cur+=mp[a]*16
            if b.isdigit():
                cur+=int(b)
            else:
                cur+=mp[b]
            arr[i]=cur
        ans=[]
        # 找到每个分量最接近的17的倍数
        for i in range(3):
            pre,idx=inf,0
            for j in range(16):
                if abs(arr[i]-j*17)<pre:
                    pre=abs(arr[i]-j*17)
                    idx=j
            # 将0-15转为16进制字符
            ch=str(idx)
            if idx>=10:
                ch=chr(idx-10+97)
            ans.append(ch*2)
        return "#"+"".join(ans)

Explore

在处理RGB颜色时选择17的倍数是因为Web颜色中常用的简化表示法。通常,每个颜色分量(R、G、B)是两位十六进制数,范围从00到FF。简化的颜色格式则将每个分量表示为相同的两个十六进制字符(如#11、#22、... #FF),这些值分别是0, 17, 34, ..., 255的十六进制表示(17的倍数)。选择17而非16或20是因为255最接近256(16的方),且可以被17整除15次,完美覆盖从0到255的范围。

因为每个颜色分量(0到255)在简化的十六进制表示中只能取#00, #11, #22, ..., #FF中的一个,这些值对应的是0*17, 1*17, 2*17, ..., 15*17。所以,在0到15的范围内遍历可以覆盖所有可能的17的倍数,确保找到与原始颜色分量最接近的简化值。

题解中使用的映射表方法是直观且易于理解的一种方式。一个更简便的方法是使用Python标准库函数`int`直接将十六进制的字符串转换为整数,例如`int('1a', 16)`将返回整数值26。这种方法可以减少代码量并可能提高一些效率。

这种返回格式遵循了Web颜色的简化表示法。在简化的十六进制颜色代码中,每个颜色分量用两个相同的十六进制数字表示(如#11、#22等),这种方法简化了颜色的指定,使得记忆和应用更为方便,尤其是在需要快速设定或调整颜色时。此外,这种格式在视觉上更为均匀和一致。