LeetCode Easy: 66
紀錄解題當下的思路與收穫的知識點

\66. Plus One

  • 沒頭緒時,可以先列出多種結果,拆解歸納相似之處
  • 像這題+1其實就只有兩種情況,9或其他
class Solution {
    /**
     * Input: digits = [4,3,2,1]
     * Output: [4,3,2,2]
     * Explanation: The array represents the integer 4321.
     * Incrementing by one gives 4321 + 1 = 4322.
     * Thus, the result should be [4,3,2,2].
     */
    // 從最後一位數開始遍歷(向前),不為9時直接加一,為9時讓當前元素重置為0(進位了)
    public int[] plusOne(int[] digits) {
        for (int i = digits.length - 1; i >= 0; i--) {
            // 如果等於 9 ,重置為0
            if (digits[i] == 9){
                digits[i] = 0;
            } else {
                // 不為9,直接加一返回
                digits[i] ++;
                return digits;
            }
        }
        // 循環出來如果沒返回(原數字剛好是999之類的情況),
        // 所有的位都已經重置為0了 ,只需要數組擴容,在第一位數加一即可
        digits = new int[digits.length + 1];
        digits[0] = 1;
        return digits;
    }
}

\67. Add Binary

  • StringBuilder的reverse()方法結合逆序遍歷,是處理字符串問題的利器
  • 「加法」系列題目優先考慮 「列豎式」模擬法
class Solution {
    /**
     * Input: a = "1010", b = "1011"
     * Output: "10101"
     */
    public String addBinary(String a, String b) {
        StringBuilder res = new StringBuilder(); // 預計返回的結果
        int i = a.length() - 1; // 標記遍歷到 a 的位置,準備從最後一位向前遍歷
        int j = b.length() - 1; // 標記遍歷到 b 的位置
        int carry = 0; // 進位
        while (i >= 0 || j >= 0 || carry != 0) { // a 沒遍歷完,或 b 沒遍歷完,或進位不為 0
            int digitA = (i >= 0 ? a.charAt(i) - '0' : 0); // 當前 a 的取值(如果是'1' - '0' 剛好就是1)
            int digitB = (j >= 0 ? b.charAt(j) - '0' : 0); // 當前 b 的取值
            int sum = digitA + digitB + carry; // 當前位置相加的結果
            carry = (sum >= 2 ? 1 : 0); // 是否有進位(相加=2就是要進位)
            sum = (sum >= 2 ? sum - 2 : sum); // 去除進位后留下的数字
            res.append(sum); // 把去除進位后留下的数字拼接到結果中
            // 若最後一次有進位也是while的第三個條件,不會遺漏
            i--;  // 遍歷到 a 的位置向左移動
            j--;  // 遍歷到 b 的位置向左移動
        }
        return res.reverse().toString(); // 把結果反轉並返回
    }
}

\69. Sqrt(x)

開方

  • 二分法重點在於區間的選擇
  • 每次疊代必須確保能縮小範圍
  • 考慮極端值是否會死循環
/**
 * Input: x = 8
 * Output: 2
 * Explanation: The square root of 8 is 2.82842...,
 * and since the decimal part is truncated, 2 is returned.
 */
public class Solution {
    public int mySqrt(int x) {
        // 特殊值判斷
        if (x == 0) {
            return 0;
        }
        if (x == 1) {
            return 1;
        }

        int left = 1;
        int right = x / 2;
        // 在區間 [left..right] 查找目標元素
        while (left < right) {
            // mid需要進位,否則最後區間剩2數時會卡死
            int mid = left + (right - left + 1) / 2;

            if (mid > x / mid) {
                // 下一輪搜索區間是 [left..mid - 1]
                right = mid - 1;
            } else {
                // 下一輪搜索區間是 [mid..right]
                left = mid;
            }
        }
        return left;
    }
}

上次修改於 2022-02-08