难度: Easy
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等),这种方法简化了颜色的指定,使得记忆和应用更为方便,尤其是在需要快速设定或调整颜色时。此外,这种格式在视觉上更为均匀和一致。