題目
假設有n枚硬幣,要擺一個階梯形,第一行1個,第二行2個,以此類推,看n枚硬幣能擺多少行,返回行數。未擺滿行的不算。
原理
二分法
先假設放 x 行需要 m 個硬幣,用 m 與 n 對比,大于 n 則縮小 x,否則增大 x,直到算出結果。
牛頓迭代
1 + 2 + 3 + …… + x = (x * x + x) / 2 = n,所以 x = 2n - x 的平方根。求平方根可以用牛頓迭代,我們可以先設 x = n,如果 2n - x 的平方根 = x,則返回結果,否則讓 x 等于計算出的平方根,如果遞歸,直到計算出結果。
代碼
二分法
public static void main(String[] args) {
System.out.println(coinByDichotomy(10));
}
private static int coinByDichotomy(int n) {
int low = 1, high = n;
while (low <= high) {
int mid = (high - low) / 2 + low;
if ((mid * mid + mid) / 2 == n) {
return mid;
}
if ((mid * mid + mid) / 2 > n) {
high = mid - 1;
} else if ((mid * mid + mid) / 2 < n) {
low = mid + 1;
}
}
return low - 1;
}
牛頓迭代
public static void main(String[] args) {
System.out.println(coinByNewton(10));
}
private static int coinByNewton(int n) {
if (n == 0 || n == 1) {
return n;
}
return (int) sqrtByNewton(n, n);
}
private static double sqrtByNewton(double x, int n) {
double res = (x + (2 * n - x) / x) / 2;
if (res == x) {
return res;
}
return sqrtByNewton(res, n);
}