題目連結:
題目意譯:
你被給定兩整數 num1 和 num2。
在一次操作中,你可以在範圍 [0, 60] 中選出一個整數 i 並從 num1 減去 2 ^ i + num2。
回傳讓 num1 變為 0 最少所需的操作數。
如果不可能使 num1 變為 0,則回傳 -1。
限制:
1 ≦ num1 ≦ 10 ^ 9
-10 ^ 9 ≦ num2 ≦ 10 ^ 9
範例測資:
範例 1:
輸入: num1 = 3, num2 = -2
輸出: 3
解釋: 我們可以藉由以下操作讓 3 變為 0:
- 我們選擇 i = 2 並從 3 減去 2 ^ 2 + (-2),3 - (4 + (-2)) = 1。
- 我們選擇 i = 2 並從 1 減去 2 ^ 2 + (-2),1 - (4 + (-2)) = -1。
- 我們選擇 i = 0 並從 -1 減去 2 ^ 0 + (-2),(-1) - (1 + (-2)) = 0。
可以證明,3 次操作為我們最少所需之操作數。
範例 2:
輸入: num1 = 5, num2 = 7
輸出: -1
解釋: 可以證明,不可能使用給定的操作來讓 5 變為 0。
解題思維:
由於我們每次最糟都可以選減去 2 ^ 60,進而抵銷加上 num2 的動作。因此如果真的可以將 num1 變為 0,則最少所需次數不會超過 60 次。
那麼我們就假設最少需要 t 次(t 從 0 一路窮舉到 60)。此時我們令 X = num1 - t × num2,這樣一來後續就不需要再擔心 num2 了。而接下來就是要檢查 X 可不可以用恰好 t 次減去某些 2 ^ i 的操作來降到 0。
首先如果 X < t,則不可能在恰好 t 次操作內達成。因為 2 ^ i 至少會是 1(即 i == 0 時)。
接著假設 X 的二進位表示法中有 C 個 1。而如果 C > t,也不可能達成。因為一次操作最多只能消掉一個 1;反之,如果 C ≦ t,則必定可以在恰好 t 次完成。因為一個位元 2 ^ j 不一定要直接用 2 ^ j 來直接消掉,可以改用 2 個 2 ^ (j - 1) 、 4 個 2 ^ (j - 2) 等等消掉;而 2 ^ (j - 1) 等又可以比照辦理。
因此可以通過檢查的最小 t 值即為所求。而 0 ~ 60 都不可行的話,則代表著 num1 不可能變成 0,因此回傳 -1。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。