In the following, every capital letter represents some hexadecimal digit from 0 to f.
The red-green-blue color "#AABBCC" can be written as "#ABC" in shorthand. For example, "#15c" is shorthand for the color "#1155cc".
Now, say the similarity between two colors "#ABCDEF" and "#UVWXYZ" is -(AB - UV)^2 - (CD - WX)^2 - (EF - YZ)^2.
Given the color "#ABCDEF", return a 7 character color that is most similar to #ABCDEF, and has a shorthand (that is, it can be represented as some "#XYZ"
Example 1: Input: color = "#09f166" Output: "#11ee66" Explanation: The similarity is -(0x09 - 0x11)^2 -(0xf1 - 0xee)^2 - (0x66 - 0x66)^2 = -64 -9 -0 = -73. This is the highest among any shorthand color.
Note:
coloris a string of length7.coloris a valid RGB color: fori > 0,color[i]is a hexadecimal digit from0tof- Any answer which has the same (highest) similarity as the best answer will be accepted.
- All inputs and outputs should use lowercase letters, and the output is 7 characters.
這道題定義了一種表示顏色的十六進制字符串,然后說是有一種兩兩字符相等的顏色可以縮寫。然后又給了我們一個人一的字符串,讓我們找出距離其最近的可以縮寫的顏色串。題意不難理解,而且還是Easy標識符,所以我們要有信心可以將其拿下。那么通過分析題目中給的例子, 我們知道可以將給定的字符串拆成三個部分,每個部分分別來進行處理,比如對於字符串"#09f166"來說,我們就分別處理"09","f1","66"即可。我們的目標是要將每部分的兩個字符變為相同,並且跟原來的距離最小,那么實際上我們並不需要遍歷所有的組合,因為比較有參考價值的就是十位上的數字,因為如果十位上的數字不變,或者只是增減1,而讓個位上的數字變動大一些,這樣距離會最小,因為個位上的數字權重最小。就拿"09"來舉例,這個數字可以變成"11"或者"00",十六進制數"11"對應的十進制數是17,跟"09"相差了8,而十六進制數"00"對應的十進制數是0,跟"09"相差了9,顯然我們選擇"11"會好一些。所以我們的臨界點是"8",如果個位上的數字大於"8",那么十位上的數就加1。
下面來看如何確定十位上的數字,比如拿"e1"來舉例,其十進制數為225,其可能的選擇有"ff","ee",和"dd",其十進制數分別為255,238,和221,我們目測很容易看出來是跟"dd"離得最近,但是怎么確定十位上的數字呢。我們發現"11","22","33","44"... 這些數字之間相差了一個"11",十進制數為17,所以我們只要將原十六進制數除以一個"11",就知道其能到達的位置,比如"e1"除以"11",就只能到達"d",那么十進制上就是"d",至於個位數的處理情況跟上面一段講解相同,我們對"11"取余,然后跟臨界點"8"比較,如果個位上的數字大於"8",那么十位上的數就加1。這樣就可以確定正確的數字了,那么組成正確的十六進制字符串即可,參見代碼如下:
解法一:
class Solution { public: string similarRGB(string color) { return "#" + helper(color.substr(1, 2)) + helper(color.substr(3, 2)) + helper(color.substr(5, 2)); } string helper(string str) { string dict = "0123456789abcdef"; int num = stoi(str, nullptr, 16); int idx = num / 17 + (num % 17 > 8 ? 1 : 0); return string(2, dict[idx]); } };
我們也可以不用helper函數,直接在一個函數中搞定即可,參見代碼如下:
解法二:
class Solution { public: string similarRGB(string color) { for (int i = 1; i < color.size(); i += 2) { int num = stoi(color.substr(i, 2), nullptr, 16); int idx = num / 17 + (num % 17 > 8 ? 1 : 0); color[i] = color[i + 1] = (idx > 9) ? (idx - 10 + 'a') : (idx + '0'); } return color; } };
參考資料:
https://leetcode.com/problems/similar-rgb-color/solution/
