1. 程式人生 > 其它 >LeetCode——258. 各位相加(Java)

LeetCode——258. 各位相加(Java)

題目描述

題幹:
給定一個非負整數 num,反覆將各個位上的數字相加,直到結果為一位數。返回這個結果。

示例 1:
輸入: num = 38
輸出: 2 
解釋: 各位相加的過程為:
38 --> 3 + 8 --> 11
11 --> 1 + 1 --> 2
由於2 是一位數,所以返回 2。

示例 1:
輸入: num = 0
輸出: 0

題解思路

將數字各位反覆相加直到和為單位數,看似題目無非就是簡單考驗個人的迴圈或遞迴思路,確有其實際意義。

首先科普這道題目真正的名字應該是求自然數的數根,首先看一下百度百科的解釋
首先數根作為自然數的性質,可作為一種檢驗計算正確性的方法。

例如,兩數字的和的數根等於兩數字分別的數根的和。

另外,數根也可以用來判斷數字的整除性,如果數根能被3或9整除,則原來的數也能被3或9整除。

我們可以看到根據數根的性質我們完全可以將程式碼演化為優雅的公式輸出,但是它的具體推導思路是什麼呢

官方題解給出的數學方法根據進位制的推導計算出和模9相關的方法確實有些晦澀,如果我們羅列一下規律可以發現

從1開始的自然數對9取模是一個從1到9的迴圈的規律,我們總結一下發現一下規律

n 是 0 ,數根就是 0。
n 不是 9 的倍數,數根就是 n 對 9 取餘,即 n mod 9。
n 是 9 的倍數,數根就是 9。

當然這個時候我們就根絕該規律條件判斷進行編寫程式碼了,還可以再進一步優化

根據數根的性質我們知道他會跟著自然數的大小同步移動,所以我們可以先將自然數進行-1再取模

這樣我們就可以避免0和9的倍數 出現0的情況,之後再+1將數根還原,直接用公式來返回答案即可

正確程式碼

// 迴圈
public int addDigits01(int num) {
    while (num >= 10) {
        int sum = 0;
        while (num > 0) {
            sum += num % 10;
            num /= 10;
        }
        num = sum;
    }
    return num;
}

// 遞迴
public int addDigits02(int num) {
    return (num - 1) % 9 + 1;
}