一、題目原型:
給定一個(gè)由整數(shù)組成的非空數(shù)組所表示的非負(fù)整數(shù),在該數(shù)的基礎(chǔ)上加一。
最高位數(shù)字存放在數(shù)組的首位, 數(shù)組中每個(gè)元素只存儲(chǔ)一個(gè)數(shù)字。
你可以假設(shè)除了整數(shù) 0 之外,這個(gè)整數(shù)不會(huì)以零開頭。
二、題目意思剖析:
示例 1:
輸入: [1,2,3]
輸出: [1,2,4]
解釋: 輸入數(shù)組表示數(shù)字 123。
示例 2:
輸入: [4,3,2,1]
輸出: [4,3,2,2]
解釋: 輸入數(shù)組表示數(shù)字 4321。
三、解題思路:
誤區(qū):我一開始的想法是把數(shù)字+1,然后再分。
但是題目的數(shù)字并沒(méi)有限制,所以,當(dāng)去取余數(shù)然后*10的多少次方時(shí),就越界了崩潰了。所以,這題不能這么做。
正解:遞歸,只能通過(guò)遞歸來(lái)算。
其實(shí)我們考慮該題的核心,應(yīng)該集中于一點(diǎn):該位+1后,是否=10
,這是問(wèn)題的核心。遞歸算法也是根據(jù)這個(gè)來(lái)展開的。
1.在這里我們先要將最后一位先判斷,是否+1后=10。如果=10,就需要進(jìn)一位,再去判斷接下來(lái)的情況;如果<10,那就直接返回原數(shù)組了。
2.至于除了最后一位的情況,其實(shí)也是和前面一樣判斷。
3.問(wèn)題核心:iscarry:是否需要進(jìn)位,也就是前一位+1后是否等于10
// 遞歸 iscarry:是否進(jìn)位,也就是他前一個(gè)數(shù)是不是等于10
func isCarry(_ index: inout Int, _ digits: inout [Int], _ iscarry: Bool) -> [Int] {
if index < 0 {
if iscarry {
// 如果這個(gè)時(shí)候數(shù)組已經(jīng)遍歷完了,但是iscarry=true,說(shuō)明還是進(jìn)位,在最前面加一個(gè)1
digits.insert(1, at: 0)
}
return digits
}
var bool: Bool = true
if index == digits.count - 1 {
let num = digits[index] + 1
if num == 10 {
digits[index] = 0
bool = true
}else {
digits[index] = num
bool = false
return digits
}
}else {
var num: Int = 0
if iscarry { //如果是進(jìn)位
num = digits[index] + 1
if num == 10 {
digits[index] = 0
bool = true
}else {
digits[index] = num
bool = false
return digits
}
}
}
index = index - 1
return isCarry(&index, &digits, bool)
}
func plusOne(_ digits: [Int]) -> [Int] {
var nums: [Int] = digits
// 默認(rèn) index = 最后一位
var index: Int = digits.count-1
return isCarry(&index, &nums, false)
}
四、小結(jié)
耗時(shí)16
毫秒,超過(guò)77.09%
的提交記錄,總提交數(shù)109
。
個(gè)人博客地址