問題
問題描述:給定一個(gè)整形數(shù)組 A
风宁,對于 A
中的每個(gè)元素 A[i]
,都可以加上一個(gè)數(shù) x
蛹疯, 其中 -K <= x <= K
戒财,然后可以得到一個(gè)新數(shù)組 B
。求出 B
中最大數(shù)與最小數(shù)的最小差值捺弦。
問題要點(diǎn):首先需要明確的是饮寞,這里的差值是指絕對值,是 >= 0
的列吼。讓 B
中最大數(shù)與最小數(shù)的差值最小幽崩,取決于怎么加 x
。
想看英文的戳這里:原題地址
解決方案
簡化問題
先簡化問題寞钥,假設(shè)有 a
慌申,b
兩個(gè)數(shù),且 a > b
理郑。a
蹄溉,b
分別加上一個(gè)數(shù)之后,a1
= a + x
您炉,b1 = b + x
柒爵,其中 -K <= x <= K
,那么a1
邻吭,b1
的最小差值是多少餐弱?
假設(shè) a
,b
的差值為 c = a - b
囱晴。
當(dāng) a
膏蚓,b
各加上一個(gè)數(shù)后,其差值為 a + x1 - (b + x2) = a - b - (x2 - x1)
畸写。由于 a-b
是正數(shù)驮瞧,則需要讓x2 - x1
越接近 c
,其差值越小枯芬,且 x2
為正數(shù)论笔。
由于 -K <= x <= K
,比較容易推斷出千所,x2 - x1
的范圍是 [-2k, 2k]
狂魔,所以其最大值為 2k
。
比如 c = 3淫痰,k = 2
最楷,x2 - x1
的范圍在 [-4, 4]
之間,也就是說完全能取到 3
,所以其最小差值為 0
籽孙。
比如 c = 5烈评,k = 1
,x2 - x1
的最大值也只能是 2
犯建,所以最小差值為 5 - 2 = 3
讲冠。
所以,按照上面的推斷适瓦,我們可以比較 c
與 2k
竿开,如果c <= 2k
,則最小差值為 0
犹菇;如果 c > 2k
德迹,則為 c - 2k
。
回到正題
那么對于A
數(shù)組來說揭芍,我們只要找到其最大值 maxA
胳搞、最小值 minA
,轉(zhuǎn)化為上面的問題即可称杨。
那為什么能保證 maxA + x1
肌毅,minA + x2
在 B
中仍然是最大值和最小值呢?因?yàn)榭梢圆僮髌渌?x姑原,使其值一定在 minA + x1 <= B[i] <= maxA + x2
之間悬而。
比如 A = [2, 4, 9], k = 3锭汛,那么 maxA - minA = 9 - 2 = 7
笨奠,則最小差值為 7 - 2k = 1
。
A -> B
變換如下唤殴,為了使得 B[1]
處于最大最小值之間般婆,需要 +1
。這只是其中的一種變換方式朵逝。
A:[2, 4, 9] => B:[2+3, 4+1, 9-3] => [5, 5, 6]
swift
代碼如下:
class Solution {
func smallestRangeI(_ A: [Int], _ K: Int) -> Int {
if A.count <= 1 {
return 0
}
var minA = A[0]
var maxA = A[0]
for a in A {
if a > maxA {
maxA = a
} else if a < minA {
minA = a
}
}
// 最大數(shù)與最小數(shù)之差
let difference = maxA - minA
// 兩個(gè)數(shù)分別加 x 后蔚袍,差值范圍 [-2k, 2k],如果能補(bǔ)齊配名,則為 0
if difference <= 2 * K {
return 0
} else {
// 補(bǔ)最大值
return difference - 2 * K
}
}
}