[LeetCode] 964. Least Operators to Express Number 表示數字的最少運算符



Given a single positive integer x, we will write an expression of the form x (op1) x (op2) x (op3) x ... where each operator op1op2, etc. is either addition, subtraction, multiplication, or division (+-*, or /).  For example, with x = 3, we might write 3 * 3 / 3 + 3 - 3 which is a value of 3.

When writing such an expression, we adhere to the following conventions:

  1. The division operator (/) returns rational numbers.
  2. There are no parentheses placed anywhere.
  3. We use the usual order of operations: multiplication and division happens before addition and subtraction.
  4. It's not allowed to use the unary negation operator (-).  For example, "x - x" is a valid expression as it only uses subtraction, but "-x + x" is not because it uses negation.

We would like to write an expression with the least number of operators such that the expression equals the given target.  Return the least number of operators used.

Example 1:

Input: x = 3, target = 19
Output: 5
Explanation: 3 * 3 + 3 * 3 + 3 / 3.  The expression contains 5 operations.

Example 2:

Input: x = 5, target = 501
Output: 8
Explanation: 5 * 5 * 5 * 5 - 5 * 5 * 5 + 5 / 5.  The expression contains 8 operations.

Example 3:

Input: x = 100, target = 100000000
Output: 3
Explanation: 100 * 100 * 100 * 100.  The expression contains 3 operations.

Note:

  • 2 <= x <= 100
  • 1 <= target <= 2 * 10^8

這道題說是給了一個正整數x,我們需要讓x通過一些運算組成另一個正整數 target,這里的x可以不限次數使用,運算只包括加減乘除,不帶括號,但需要滿足乘除優先的基本規律。並且這里的除法是整數除法,減號不能當作負數符號使用,讓我們求要組成 target 的最少的運算符的使用個數。雖然題目很長不好理解,但是通過例子還是不難理解題意的,難就難在如何解題。博主看了一會兒,發現沒思路就直接放棄了,直奔論壇上找解法。這里直接參考 donggua_fu 大神的解法吧,首先處理 edge cases,當 x 等於 target 的話,不用加任何運算符,返回0即可。若 x 大於 target,比如 x=5,target=3,我們其實可以迅速的求出運算符的個數,因為5比3大,要湊3就只能先變成1,這里就有兩種變法,一種是全部都變成1,然后來湊3,即 5/5 + 5/5 + 5/5,這時的運算符個數是 target * 2 -1,因為加號的個數總是比除號少一個。另一種湊法就是 5 - 5/5 - 5/5,這時候的運算符個數是 (x - target) * 2,此時的加號和除號的個數相同,均為x和 target 的差值。

接下來就要處理 x 小於 target 的情況了,此時由於不知道x到底比 target 小多少,若差距太大的話,肯定不能用加號,所以應該先用乘號來讓x變大,直到剛好大於等於 target 停止,並每次增加次數 cnt。若此時 sum 正好等於 target,太幸運了,直接返回 cnt。但通常情況下 sum 會大於 target,此時 sum - target 的差值就需要另行計算了。這里差值跟 target 的大小關系又要分為兩種情況來討論,當 sum - target < target 時,比如 x=5,sum=25,target=15,則 sum - target=10,就是說現在已經乘到了 25,但需要再減去 10,這個差值 10 可以再次調用原函數來計算,此時新的 target 代入 10 即可,記得返回值要加上 cnt。當然之后還是要再計算一下另一種湊的方法,由於 sum 超過了 target,所以回退一個x,變成 sum / x,此時小於 target,那么它們的差值 target - (sum / x) 就可以通過再次調用函數來計算,注意這里加上 cnt 之后還要減去1,因為回退了一個x,少了一個乘號。最終二者的較小值即為所求,記得要加上個1,以為多加了個運算符,參見代碼如下:


class Solution {
public:
    int leastOpsExpressTarget(int x, int target) {
        if (x == target) return 0;
        if (x > target) {
            return min(target * 2 - 1, (x - target) * 2);
        }
        long sum = x;
        int cnt = 0;
        while (sum < target) {
            sum *= x;
            ++cnt;
        }
        if (sum == target) return cnt;
        int res1 = INT_MAX, res2 = INT_MAX;
        if (sum - target < target) {
            res1 = leastOpsExpressTarget(x, sum - target) + cnt;
        }
        res2 = leastOpsExpressTarget(x, target - (sum / x)) + cnt - 1;
        return min(res1, res2) + 1;
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/964


參考資料:

https://leetcode.com/problems/least-operators-to-express-number/

https://leetcode.com/problems/least-operators-to-express-number/discuss/208445/c%2B%2B-recursive-easy-to-understand

https://leetcode.com/problems/least-operators-to-express-number/discuss/208349/JavaC%2B%2BPython-O(logY)-Time-and-O(1)-Space


LeetCode All in One 題目講解匯總(持續更新中...)【】


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM